VGroup Modifiers: added mapping options to proximity and edit.

*Added Smooth/Sharp/Root/etc. mappings to WeightVGEdit modifier, in addition to custom curve one.
*Added Smooth/Sharp/Root/etc. mappings to WeightVGProximity modifier, without the custom curve one!
*Factorized the common mapping code into MOD_weightvg_util.
This commit is contained in:
Bastien Montagne 2011-09-05 16:16:00 +00:00
parent cc906e0e2a
commit 4393df9320
7 changed files with 149 additions and 116 deletions

@ -779,32 +779,11 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col.label(text="Default Weight:") col.label(text="Default Weight:")
col.prop(md, "default_weight", text="") col.prop(md, "default_weight", text="")
# layout.prop(md, "use_map") layout.prop(md, "mapping_mode")
# if md.use_map: if md.mapping_mode == 'CURVE':
# split = layout.split()
# col = split.column()
# col.label("Input:")
# col.label("Output:")
# col = split.column()
# col.prop(md, "map_input_low", text="Min")
# col.prop(md, "map_output_low", text="Min")
# col = split.column()
# col.prop(md, "map_input_high", text="Max")
# col.prop(md, "map_output_high", text="Max")
layout.prop(md, "use_map_curve")
if md.use_map_curve:
col = layout.column() col = layout.column()
col.template_curve_mapping(md, "map_curve") col.template_curve_mapping(md, "map_curve")
# layout.prop(md, "use_reverse")
# layout.prop(md, "use_clamp")
# if md.use_clamp:
# row = layout.row()
# row.prop(md, "clamp_weight_min")
# row.prop(md, "clamp_weight_max")
row = layout.row() row = layout.row()
row.prop(md, "use_add") row.prop(md, "use_add")
row.prop(md, "use_remove") row.prop(md, "use_remove")
@ -864,6 +843,8 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
row.prop(md, "min_dist") row.prop(md, "min_dist")
row.prop(md, "max_dist") row.prop(md, "max_dist")
layout.prop(md, "mapping_mode")
# Common mask options… # Common mask options…
layout.separator() layout.separator()
self.weight_vg_mask(layout, ob, md) self.weight_vg_mask(layout, ob, md)

@ -795,8 +795,8 @@ typedef struct WeightVGEditModifierData {
char defgrp_name[32]; /* Name of vertex group to edit. */ char defgrp_name[32]; /* Name of vertex group to edit. */
short edit_flags; /* using MOD_WVG_EDIT_* flags */ short edit_flags; /* Using MOD_WVG_EDIT_* flags. */
short pad1; short mapping_mode; /* Using MOD_WVG_MAPPING_* defines. */
float default_weight; /* Weight for vertices not in vgroup. */ float default_weight; /* Weight for vertices not in vgroup. */
/* Mapping stuff. */ /* Mapping stuff. */
@ -817,6 +817,7 @@ typedef struct WeightVGEditModifierData {
/* How to map the texture (using MOD_DISP_MAP_* constants). */ /* How to map the texture (using MOD_DISP_MAP_* constants). */
int mask_tex_mapping; int mask_tex_mapping;
char mask_tex_uvlayer_name[32]; /* Name of the UV layer. */ char mask_tex_uvlayer_name[32]; /* Name of the UV layer. */
/* Padding… */ /* Padding… */
int pad_i1; int pad_i1;
} WeightVGEditModifierData; } WeightVGEditModifierData;
@ -825,7 +826,7 @@ typedef struct WeightVGEditModifierData {
/* Use parametric mapping. */ /* Use parametric mapping. */
//#define MOD_WVG_EDIT_MAP (1 << 0) //#define MOD_WVG_EDIT_MAP (1 << 0)
/* Use curve mapping. */ /* Use curve mapping. */
#define MOD_WVG_EDIT_CMAP (1 << 1) //#define MOD_WVG_EDIT_CMAP (1 << 1)
/* Reverse weights (in the [0.0, 1.0] standard range). */ /* Reverse weights (in the [0.0, 1.0] standard range). */
//#define MOD_WVG_EDIT_REVERSE_WEIGHTS (1 << 2) //#define MOD_WVG_EDIT_REVERSE_WEIGHTS (1 << 2)
/* Add vertices with higher weight than threshold to vgroup. */ /* Add vertices with higher weight than threshold to vgroup. */
@ -848,7 +849,7 @@ typedef struct WeightVGMixModifierData {
char mix_mode; /* How second vgroups weights affect first ones */ char mix_mode; /* How second vgroups weights affect first ones */
char mix_set; /* What vertices to affect. */ char mix_set; /* What vertices to affect. */
char pad[6]; char pad_c1[6];
/* Masking options. */ /* Masking options. */
float mask_constant; /* The global "influence", if no vgroup nor tex is used as mask. */ float mask_constant; /* The global "influence", if no vgroup nor tex is used as mask. */
@ -861,8 +862,9 @@ typedef struct WeightVGMixModifierData {
struct Object *mask_tex_map_obj; /* Name of the map object. */ struct Object *mask_tex_map_obj; /* Name of the map object. */
int mask_tex_mapping; /* How to map the texture! */ int mask_tex_mapping; /* How to map the texture! */
char mask_tex_uvlayer_name[32]; /* Name of the UV layer. */ char mask_tex_uvlayer_name[32]; /* Name of the UV layer. */
/* Padding… */ /* Padding… */
int pad2; int pad_i1;
} WeightVGMixModifierData; } WeightVGMixModifierData;
/* How second vgroup's weights affect first ones. */ /* How second vgroup's weights affect first ones. */
@ -910,8 +912,11 @@ typedef struct WeightVGProximityModifierData {
float min_dist, max_dist; /* Distances mapping to 0.0/1.0 weights. */ float min_dist, max_dist; /* Distances mapping to 0.0/1.0 weights. */
/* Put here to avoid breaking existing struct... */
short mapping_mode; /* Using MOD_WVG_MAPPING_* defines. */
/* Padding... */ /* Padding... */
int pad; short pad_s1;
} WeightVGProximityModifierData; } WeightVGProximityModifierData;
/* Modes of proximity weighting. */ /* Modes of proximity weighting. */
@ -929,6 +934,18 @@ typedef struct WeightVGProximityModifierData {
#define MOD_WVG_PROXIMITY_GEOM_FACES (1 << 2) #define MOD_WVG_PROXIMITY_GEOM_FACES (1 << 2)
/* Defines common to all WeightVG modifiers. */ /* Defines common to all WeightVG modifiers. */
/* Mapping modes. */
#define MOD_WVG_MAPPING_NONE 0
#define MOD_WVG_MAPPING_CURVE 1
#define MOD_WVG_MAPPING_SHARP 2 /* PROP_SHARP */
#define MOD_WVG_MAPPING_SMOOTH 3 /* PROP_SMOOTH */
#define MOD_WVG_MAPPING_ROOT 4 /* PROP_ROOT */
/* PROP_LIN not used (same as NONE, here...). */
/* PROP_CONST not used. */
#define MOD_WVG_MAPPING_SPHERE 7 /* PROP_SPHERE */
#define MOD_WVG_MAPPING_RANDOM 8 /* PROP_RANDOM */
#define MOD_WVG_MAPPING_STEP 9 /* Median Step. */
/* Tex channel to be used as mask. */ /* Tex channel to be used as mask. */
#define MOD_WVG_MASK_TEX_USE_INT 1 #define MOD_WVG_MASK_TEX_USE_INT 1
#define MOD_WVG_MASK_TEX_USE_RED 2 #define MOD_WVG_MASK_TEX_USE_RED 2

@ -2552,6 +2552,17 @@ static void rna_def_modifier_weightvg_mask(BlenderRNA *brna, StructRNA *srna)
static void rna_def_modifier_weightvgedit(BlenderRNA *brna) static void rna_def_modifier_weightvgedit(BlenderRNA *brna)
{ {
static EnumPropertyItem weightvg_edit_mapping_mode_items[] = {
{MOD_WVG_MAPPING_NONE, "LINEAR", ICON_LINCURVE, "Linear", ""},
{MOD_WVG_MAPPING_CURVE, "CURVE", ICON_RNDCURVE, "Custom Curve", ""},
{MOD_WVG_MAPPING_SHARP, "SHARP", ICON_SHARPCURVE, "Sharp", ""},
{MOD_WVG_MAPPING_SMOOTH, "SMOOTH", ICON_SMOOTHCURVE, "Smooth", ""},
{MOD_WVG_MAPPING_ROOT, "ROOT", ICON_ROOTCURVE, "Root", ""},
{MOD_WVG_MAPPING_SPHERE, "ICON_SPHERECURVE", ICON_SPHERECURVE, "Sphere", ""},
{MOD_WVG_MAPPING_RANDOM, "RANDOM", ICON_RNDCURVE, "Random", ""},
{MOD_WVG_MAPPING_STEP, "STEP", ICON_NOCURVE, "Median Step", ""}, /* Would need a better icon... */
{0, NULL, 0, NULL, NULL}};
StructRNA *srna; StructRNA *srna;
PropertyRNA *prop; PropertyRNA *prop;
@ -2567,21 +2578,11 @@ static void rna_def_modifier_weightvgedit(BlenderRNA *brna)
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WeightVGModifier_vgroup_set"); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WeightVGModifier_vgroup_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update"); RNA_def_property_update(prop, 0, "rna_Modifier_update");
/* prop= RNA_def_property(srna, "use_map", PROP_BOOLEAN, PROP_NONE);*/ prop= RNA_def_property(srna, "mapping_mode", PROP_ENUM, PROP_NONE);
/* RNA_def_property_boolean_sdna(prop, NULL, "edit_flags", MOD_WVG_EDIT_MAP);*/ RNA_def_property_enum_items(prop, weightvg_edit_mapping_mode_items);
/* RNA_def_property_ui_text(prop, "Map", "Map vertex group weights.");*/ RNA_def_property_ui_text(prop, "Mapping Mode", "How weights are mapped to there new values.");
/* RNA_def_property_update(prop, 0, "rna_Modifier_update");*/
prop= RNA_def_property(srna, "use_map_curve", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "edit_flags", MOD_WVG_EDIT_CMAP);
RNA_def_property_ui_text(prop, "Curve Map", "Map vertex group weights with a curve.");
RNA_def_property_update(prop, 0, "rna_Modifier_update"); RNA_def_property_update(prop, 0, "rna_Modifier_update");
/* prop= RNA_def_property(srna, "use_reverse", PROP_BOOLEAN, PROP_NONE);*/
/* RNA_def_property_boolean_sdna(prop, NULL, "edit_flags", MOD_WVG_EDIT_REVERSE_WEIGHTS);*/
/* RNA_def_property_ui_text(prop, "Reverse", "Reverse vertex group weights.");*/
/* RNA_def_property_update(prop, 0, "rna_Modifier_update");*/
prop= RNA_def_property(srna, "use_add", PROP_BOOLEAN, PROP_NONE); prop= RNA_def_property(srna, "use_add", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "edit_flags", MOD_WVG_EDIT_ADD2VG); RNA_def_property_boolean_sdna(prop, NULL, "edit_flags", MOD_WVG_EDIT_ADD2VG);
RNA_def_property_ui_text(prop, "Group Add", "Add vertices with weight over threshold " RNA_def_property_ui_text(prop, "Group Add", "Add vertices with weight over threshold "
@ -2594,11 +2595,6 @@ static void rna_def_modifier_weightvgedit(BlenderRNA *brna)
"from vgroup."); "from vgroup.");
RNA_def_property_update(prop, 0, "rna_Modifier_update"); RNA_def_property_update(prop, 0, "rna_Modifier_update");
/* prop= RNA_def_property(srna, "use_clamp", PROP_BOOLEAN, PROP_NONE);*/
/* RNA_def_property_boolean_sdna(prop, NULL, "edit_flags", MOD_WVG_EDIT_CLAMP);*/
/* RNA_def_property_ui_text(prop, "Clamp", "Clamp vertex group weights.");*/
/* RNA_def_property_update(prop, 0, "rna_Modifier_update");*/
prop= RNA_def_property(srna, "default_weight", PROP_FLOAT, PROP_NONE); prop= RNA_def_property(srna, "default_weight", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0, 1.0f); RNA_def_property_range(prop, 0.0, 1.0f);
RNA_def_property_ui_range(prop, 0.0, 1.0, 10, 0); RNA_def_property_ui_range(prop, 0.0, 1.0, 10, 0);
@ -2606,34 +2602,6 @@ static void rna_def_modifier_weightvgedit(BlenderRNA *brna)
"it is not in the vgroup."); "it is not in the vgroup.");
RNA_def_property_update(prop, 0, "rna_Modifier_update"); RNA_def_property_update(prop, 0, "rna_Modifier_update");
/* prop= RNA_def_property(srna, "map_input_low", PROP_FLOAT, PROP_NONE);*/
/* RNA_def_property_float_sdna(prop, NULL, "map_org_min");*/
/* RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);*/
/* RNA_def_property_ui_range(prop, -100000.0, 100000.0, 10, 0);*/
/* RNA_def_property_ui_text(prop, "Input Low Weight", "Low input mapping value.");*/
/* RNA_def_property_update(prop, 0, "rna_Modifier_update");*/
/* prop= RNA_def_property(srna, "map_input_high", PROP_FLOAT, PROP_NONE);*/
/* RNA_def_property_float_sdna(prop, NULL, "map_org_max");*/
/* RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);*/
/* RNA_def_property_ui_range(prop, -100000.0, 100000.0, 10, 0);*/
/* RNA_def_property_ui_text(prop, "Input High Weight", "High input mapping value.");*/
/* RNA_def_property_update(prop, 0, "rna_Modifier_update");*/
/* prop= RNA_def_property(srna, "map_output_low", PROP_FLOAT, PROP_NONE);*/
/* RNA_def_property_float_sdna(prop, NULL, "map_new_min");*/
/* RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);*/
/* RNA_def_property_ui_range(prop, -100000.0, 100000.0, 10, 0);*/
/* RNA_def_property_ui_text(prop, "Output Low Weight", "Low output mapping value.");*/
/* RNA_def_property_update(prop, 0, "rna_Modifier_update");*/
/* prop= RNA_def_property(srna, "map_output_high", PROP_FLOAT, PROP_NONE);*/
/* RNA_def_property_float_sdna(prop, NULL, "map_new_max");*/
/* RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);*/
/* RNA_def_property_ui_range(prop, -100000.0, 100000.0, 10, 0);*/
/* RNA_def_property_ui_text(prop, "Output High Weight", "High output mapping value.");*/
/* RNA_def_property_update(prop, 0, "rna_Modifier_update");*/
prop= RNA_def_property(srna, "map_curve", PROP_POINTER, PROP_NONE); prop= RNA_def_property(srna, "map_curve", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "cmap_curve"); RNA_def_property_pointer_sdna(prop, NULL, "cmap_curve");
RNA_def_property_ui_text(prop, "Mapping Curve", "Custom mapping curve."); RNA_def_property_ui_text(prop, "Mapping Curve", "Custom mapping curve.");
@ -2655,18 +2623,6 @@ static void rna_def_modifier_weightvgedit(BlenderRNA *brna)
"to be removed from the vgroup."); "to be removed from the vgroup.");
RNA_def_property_update(prop, 0, "rna_Modifier_update"); RNA_def_property_update(prop, 0, "rna_Modifier_update");
/* prop= RNA_def_property(srna, "clamp_weight_min", PROP_FLOAT, PROP_NONE);*/
/* RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);*/
/* RNA_def_property_ui_range(prop, -100000.0, 100000.0, 10, 0);*/
/* RNA_def_property_ui_text(prop, "Min Weight", "Lowest weight a vertex can get.");*/
/* RNA_def_property_update(prop, 0, "rna_Modifier_update");*/
/* prop= RNA_def_property(srna, "clamp_weight_max", PROP_FLOAT, PROP_NONE);*/
/* RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);*/
/* RNA_def_property_ui_range(prop, -100000.0, 100000.0, 10, 0);*/
/* RNA_def_property_ui_text(prop, "Max Weight", "Highest weight a vertex can get.");*/
/* RNA_def_property_update(prop, 0, "rna_Modifier_update");*/
/* Common masking properties. */ /* Common masking properties. */
rna_def_modifier_weightvg_mask(brna, srna); rna_def_modifier_weightvg_mask(brna, srna);
} }
@ -2756,6 +2712,17 @@ static void rna_def_modifier_weightvgproximity(BlenderRNA *brna)
{MOD_WVG_PROXIMITY_GEOM_FACES, "FACE", ICON_FACESEL, "Face", ""}, {MOD_WVG_PROXIMITY_GEOM_FACES, "FACE", ICON_FACESEL, "Face", ""},
{0, NULL, 0, NULL, NULL}}; {0, NULL, 0, NULL, NULL}};
static EnumPropertyItem weightvg_proximity_mapping_mode_items[] = {
{MOD_WVG_MAPPING_NONE, "LINEAR", ICON_LINCURVE, "Linear", ""},
/* No curve mapping here! */
{MOD_WVG_MAPPING_SHARP, "SHARP", ICON_SHARPCURVE, "Sharp", ""},
{MOD_WVG_MAPPING_SMOOTH, "SMOOTH", ICON_SMOOTHCURVE, "Smooth", ""},
{MOD_WVG_MAPPING_ROOT, "ROOT", ICON_ROOTCURVE, "Root", ""},
{MOD_WVG_MAPPING_SPHERE, "ICON_SPHERECURVE", ICON_SPHERECURVE, "Sphere", ""},
{MOD_WVG_MAPPING_RANDOM, "RANDOM", ICON_RNDCURVE, "Random", ""},
{MOD_WVG_MAPPING_STEP, "STEP", ICON_NOCURVE, "Median Step", ""}, /* Would need a better icon... */
{0, NULL, 0, NULL, NULL}};
StructRNA *srna; StructRNA *srna;
PropertyRNA *prop; PropertyRNA *prop;
@ -2802,6 +2769,11 @@ static void rna_def_modifier_weightvgproximity(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Highest Dist", "Distance mapping to weight 1.0."); RNA_def_property_ui_text(prop, "Highest Dist", "Distance mapping to weight 1.0.");
RNA_def_property_update(prop, 0, "rna_Modifier_update"); RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop= RNA_def_property(srna, "mapping_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, weightvg_proximity_mapping_mode_items);
RNA_def_property_ui_text(prop, "Mapping Mode", "How weights are mapped to there new values.");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
/* Common masking properties. */ /* Common masking properties. */
rna_def_modifier_weightvg_mask(brna, srna); rna_def_modifier_weightvg_mask(brna, srna);
} }

@ -33,16 +33,19 @@
* Or the WeightPaint mode code itself? * Or the WeightPaint mode code itself?
*/ */
#include "BLI_utildefines.h"
#include "BLI_math.h" #include "BLI_math.h"
#include "BLI_rand.h"
#include "BLI_string.h" #include "BLI_string.h"
#include "BLI_utildefines.h"
#include "DNA_color_types.h" /* CurveMapping. */
#include "DNA_mesh_types.h" #include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h" #include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h" #include "DNA_modifier_types.h"
#include "DNA_object_types.h" #include "DNA_object_types.h"
#include "BKE_cdderivedmesh.h" #include "BKE_cdderivedmesh.h"
#include "BKE_colortools.h" /* CurveMapping. */
#include "BKE_deform.h" #include "BKE_deform.h"
#include "BKE_mesh.h" #include "BKE_mesh.h"
#include "BKE_modifier.h" #include "BKE_modifier.h"
@ -54,16 +57,69 @@
#include "MOD_weightvg_util.h" #include "MOD_weightvg_util.h"
#include "RE_shader_ext.h" /* Texture masking. */ #include "RE_shader_ext.h" /* Texture masking. */
/* Maps new_w weights in place, using either one of the predifined functions, or a custom curve.
* Return values are in new_w.
* If indices is not NULL, it must be a table of same length as org_w and new_w, mapping to the real
* vertex index (in case the weight tables do not cover the whole vertices...).
* cmap might be NULL, in which case curve mapping mode will return unmodified data.
*/
void weightvg_do_map(int num, float *new_w, short mode, CurveMapping *cmap)
{
int i;
/* Return immediately, if we have nothing to do! */
/* Also security checks... */
if(((mode == MOD_WVG_MAPPING_CURVE) && (cmap == NULL))
|| !ELEM7(mode, MOD_WVG_MAPPING_CURVE, MOD_WVG_MAPPING_SHARP, MOD_WVG_MAPPING_SMOOTH,
MOD_WVG_MAPPING_ROOT, MOD_WVG_MAPPING_SPHERE, MOD_WVG_MAPPING_RANDOM,
MOD_WVG_MAPPING_STEP))
return;
/* Map each weight (vertex) to its new value, accordingly to the chosen mode. */
for(i = 0; i < num; ++i) {
float fac = new_w[i];
/* Code borrowed from the warp modifier. */
/* Closely matches PROP_SMOOTH and similar. */
switch(mode) {
case MOD_WVG_MAPPING_CURVE:
fac = curvemapping_evaluateF(cmap, 0, fac);
break;
case MOD_WVG_MAPPING_SHARP:
fac = fac*fac;
break;
case MOD_WVG_MAPPING_SMOOTH:
fac = 3.0f*fac*fac - 2.0f*fac*fac*fac;
break;
case MOD_WVG_MAPPING_ROOT:
fac = (float)sqrt(fac);
break;
case MOD_WVG_MAPPING_SPHERE:
fac = (float)sqrt(2*fac - fac * fac);
break;
case MOD_WVG_MAPPING_RANDOM:
BLI_srand(BLI_rand()); /* random seed */
fac = BLI_frand()*fac;
break;
case MOD_WVG_MAPPING_STEP:
fac = (fac >= 0.5f)?1.0f:0.0f;
break;
}
new_w[i] = fac;
}
}
/* Applies new_w weights to org_w ones, using either a texture, vgroup or constant value as factor. /* Applies new_w weights to org_w ones, using either a texture, vgroup or constant value as factor.
* Return values are in org_w. * Return values are in org_w.
* If indices is not NULL, it must be a table of same length as org_w and new_w, mapping to the real * If indices is not NULL, it must be a table of same length as org_w and new_w, mapping to the real
* vertex index (in case the weight tables do not cover the whole vertices...). * vertex index (in case the weight tables do not cover the whole vertices...).
* XXX The standard factor value is assumed in [0.0, 1.0] range. Else, weird results might appear. * XXX The standard factor value is assumed in [0.0, 1.0] range. Else, weird results might appear.
*/ */
void weightvg_do_mask(int num, int *indices, float *org_w, float *new_w, Object *ob, void weightvg_do_mask(int num, const int *indices, float *org_w, const float *new_w,
DerivedMesh *dm, float fact, const char defgrp_name[32], Tex *texture, Object *ob, DerivedMesh *dm, float fact, const char defgrp_name[32],
int tex_use_channel, int tex_mapping, Object *tex_map_object, Tex *texture, int tex_use_channel, int tex_mapping,
const char *tex_uvlayer_name) Object *tex_map_object, const char *tex_uvlayer_name)
{ {
int ref_didx; int ref_didx;
int i; int i;

@ -37,11 +37,10 @@
/* so modifier types match their defines */ /* so modifier types match their defines */
#include "MOD_modifiertypes.h" #include "MOD_modifiertypes.h"
struct Tex; struct CurveMapping;
struct DerivedMesh; struct DerivedMesh;
struct Object; struct Object;
/*struct ModifierData; struct Tex;
struct MappingInfoModifierData;*/
/* /*
* XXX I'd like to make modified weights visible in WeightPaint mode, * XXX I'd like to make modified weights visible in WeightPaint mode,
@ -61,14 +60,22 @@ struct MappingInfoModifierData;*/
*/ */
#define MOD_WVG_ZEROFLOOR 1.0e-32f #define MOD_WVG_ZEROFLOOR 1.0e-32f
/* Maps new_w weights in place, using either one of the predifined functions, or a custom curve.
* Return values are in new_w.
* If indices is not NULL, it must be a table of same length as org_w and new_w, mapping to the real
* vertex index (in case the weight tables do not cover the whole vertices...).
* cmap might be NULL, in which case curve mapping mode will return unmodified data.
*/
void weightvg_do_map(int num, float *new_w, short mode, struct CurveMapping *cmap);
/* Applies new_w weights to org_w ones, using either a texture, vgroup or constant value as factor. /* Applies new_w weights to org_w ones, using either a texture, vgroup or constant value as factor.
* Return values are in org_w. * Return values are in org_w.
* If indices is not NULL, it must be a table of same length as org_w and new_w, mapping to the real * If indices is not NULL, it must be a table of same length as org_w and new_w, mapping to the real
* vertex index (in case the weight tables do not cover the whole vertices...). * vertex index (in case the weight tables do not cover the whole vertices...).
* XXX The standard factor value is assumed in [0.0, 1.0] range. Else, weird results might appear. * XXX The standard factor value is assumed in [0.0, 1.0] range. Else, weird results might appear.
*/ */
void weightvg_do_mask(int num, int *indices, float *org_w, float *new_w, Object *ob, void weightvg_do_mask(int num, const int *indices, float *org_w, const float *new_w, Object *ob,
struct DerivedMesh *dm, float fact, const char defgrp_name[32], Tex *texture, DerivedMesh *dm, float fact, const char defgrp_name[32], Tex *texture,
int tex_use_channel, int tex_mapping, Object *tex_map_object, int tex_use_channel, int tex_mapping, Object *tex_map_object,
const char *tex_uvlayer_name); const char *tex_uvlayer_name);

@ -62,6 +62,7 @@ static void initData(ModifierData *md)
{ {
WeightVGEditModifierData *wmd = (WeightVGEditModifierData*) md; WeightVGEditModifierData *wmd = (WeightVGEditModifierData*) md;
wmd->edit_flags = 0; wmd->edit_flags = 0;
wmd->mapping_mode = MOD_WVG_MAPPING_NONE;
wmd->default_weight = 0.0f; wmd->default_weight = 0.0f;
wmd->cmap_curve = curvemapping_add(1, 0.0, 0.0, 1.0, 1.0); wmd->cmap_curve = curvemapping_add(1, 0.0, 0.0, 1.0, 1.0);
@ -89,6 +90,7 @@ static void copyData(ModifierData *md, ModifierData *target)
BLI_strncpy(twmd->defgrp_name, wmd->defgrp_name, sizeof(twmd->defgrp_name)); BLI_strncpy(twmd->defgrp_name, wmd->defgrp_name, sizeof(twmd->defgrp_name));
twmd->edit_flags = wmd->edit_flags; twmd->edit_flags = wmd->edit_flags;
twmd->mapping_mode = wmd->mapping_mode;
twmd->default_weight = wmd->default_weight; twmd->default_weight = wmd->default_weight;
twmd->cmap_curve = curvemapping_copy(wmd->cmap_curve); twmd->cmap_curve = curvemapping_copy(wmd->cmap_curve);
@ -192,7 +194,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
int i; int i;
char rel_ret = 0; /* Boolean, whether we have to release ret dm or not, when not using it! */ char rel_ret = 0; /* Boolean, whether we have to release ret dm or not, when not using it! */
/* Flags. */ /* Flags. */
int do_map = (wmd->edit_flags & MOD_WVG_EDIT_CMAP) != 0;
int do_add = (wmd->edit_flags & MOD_WVG_EDIT_ADD2VG) != 0; int do_add = (wmd->edit_flags & MOD_WVG_EDIT_ADD2VG) != 0;
int do_rem = (wmd->edit_flags & MOD_WVG_EDIT_REMFVG) != 0; int do_rem = (wmd->edit_flags & MOD_WVG_EDIT_REMFVG) != 0;
@ -264,11 +265,11 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
if(dw) { if(dw) {
org_w[i] = new_w[i] = dw->weight; org_w[i] = new_w[i] = dw->weight;
} }
}
/* Do mapping. */ /* Do mapping. */
if (do_map) { if (wmd->mapping_mode != MOD_WVG_MAPPING_NONE) {
new_w[i] = curvemapping_evaluateF(wmd->cmap_curve, 0, new_w[i]); weightvg_do_map(numVerts, new_w, wmd->mapping_mode, wmd->cmap_curve);
}
} }
/* Do masking. */ /* Do masking. */

@ -33,10 +33,10 @@
* Or the WeightPaint mode code itself? * Or the WeightPaint mode code itself?
*/ */
#include "BLI_utildefines.h" #include "BLI_editVert.h"
#include "BLI_math.h" #include "BLI_math.h"
#include "BLI_string.h" #include "BLI_string.h"
#include "BLI_editVert.h" #include "BLI_utildefines.h"
#include "DNA_mesh_types.h" #include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h" #include "DNA_meshdata_types.h"
@ -193,9 +193,9 @@ static float get_ob2ob_distance(const Object* ob, const Object* obr)
} }
/** /**
* Maps distances to weights. * Maps distances to weights, with an optionnal smoothing mapping.
*/ */
void do_map(float *weights, const int nidx, const float min_d, const float max_d) void do_map(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 */ const float range_inv= 1.0f / (max_d - min_d); /* invert since multiplication is faster */
unsigned int i= nidx; unsigned int i= nidx;
@ -204,17 +204,12 @@ void do_map(float *weights, const int nidx, const float min_d, const float max_d
else if(weights[i] <= min_d) weights[i]= 0.0f; else if(weights[i] <= min_d) weights[i]= 0.0f;
else weights[i]= (weights[i] - min_d) * range_inv; else weights[i]= (weights[i] - min_d) * range_inv;
} }
if(!ELEM(mode, MOD_WVG_MAPPING_NONE, MOD_WVG_MAPPING_CURVE)) {
weightvg_do_map(nidx, weights, mode, NULL);
}
} }
/*a min_d + b = 0.0*/
/*a max_d + b = 1.0*/
/*a min_d = -b*/
/*a = -b / min_d*/
/*max_d(-b/min_d) + b = 1.0*/
/*b((-max_d/min_d)+1.0) = 1.0*/
/*b = 1.0 / ((min_d-max_d)/min_d)*/
/*b = min_d/(min_d-max_d)*/
/************************************** /**************************************
* Modifiers functions. * * Modifiers functions. *
**************************************/ **************************************/
@ -225,6 +220,8 @@ static void initData(ModifierData *md)
wmd->proximity_mode = MOD_WVG_PROXIMITY_OBJECT; wmd->proximity_mode = MOD_WVG_PROXIMITY_OBJECT;
wmd->proximity_flags = MOD_WVG_PROXIMITY_GEOM_VERTS; wmd->proximity_flags = MOD_WVG_PROXIMITY_GEOM_VERTS;
wmd->mapping_mode = MOD_WVG_MAPPING_NONE;
wmd->mask_constant = 1.0f; wmd->mask_constant = 1.0f;
wmd->mask_tex_use_channel = MOD_WVG_MASK_TEX_USE_INT; /* Use intensity by default. */ wmd->mask_tex_use_channel = MOD_WVG_MASK_TEX_USE_INT; /* Use intensity by default. */
wmd->mask_tex_mapping = MOD_DISP_MAP_LOCAL; wmd->mask_tex_mapping = MOD_DISP_MAP_LOCAL;
@ -241,6 +238,8 @@ static void copyData(ModifierData *md, ModifierData *target)
twmd->proximity_flags = wmd->proximity_flags; twmd->proximity_flags = wmd->proximity_flags;
twmd->proximity_ob_target = wmd->proximity_ob_target; twmd->proximity_ob_target = wmd->proximity_ob_target;
twmd->mapping_mode = wmd->mapping_mode;
twmd->mask_constant = wmd->mask_constant; twmd->mask_constant = wmd->mask_constant;
BLI_strncpy(twmd->mask_defgrp_name, wmd->mask_defgrp_name, sizeof(twmd->mask_defgrp_name)); BLI_strncpy(twmd->mask_defgrp_name, wmd->mask_defgrp_name, sizeof(twmd->mask_defgrp_name));
twmd->mask_texture = wmd->mask_texture; twmd->mask_texture = wmd->mask_texture;
@ -499,7 +498,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
wmd->mask_tex_mapping, wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name); wmd->mask_tex_mapping, wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name);
/* Map distances to weights. */ /* Map distances to weights. */
do_map(org_w, numIdx, wmd->min_dist, wmd->max_dist); do_map(org_w, numIdx, wmd->min_dist, wmd->max_dist, wmd->mapping_mode);
/* Update vgroup. Note we never add nor remove vertices from vgroup here. */ /* Update vgroup. Note we never add nor remove vertices from vgroup here. */
weightvg_update_vg(dvert, defgrp_idx, numIdx, indices, org_w, 0, 0.0f, 0, 0.0f); weightvg_update_vg(dvert, defgrp_idx, numIdx, indices, org_w, 0, 0.0f, 0, 0.0f);