[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [43610] trunk/blender/source/blender: Add weight preview to WeightVG modifiers, and first, simple/ basic refactor of how modifiers can generate preview.
Bastien Montagne
montagne29 at wanadoo.fr
Sun Jan 22 18:54:32 CET 2012
Revision: 43610
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=43610
Author: mont29
Date: 2012-01-22 17:54:23 +0000 (Sun, 22 Jan 2012)
Log Message:
-----------
Add weight preview to WeightVG modifiers, and first, simple/basic refactor of how modifiers can generate preview.
User side:
* Preview for DynamicPaint should keep the same behavior (for now). Weight preview should be somawhat quicker, though.
* Preview for WeightVG modifiers is only active in WeightPaint mode, and if the affected vgroup is the active one.
* Last active preview modifier in stack wins!
Note: that modifier preview topic is yet to be further refined, quite raw/incomplete for now.
Dev side:
* In draw code, renamed DRAW_DYNAMIC_PAINT_PREVIEW flag to DRAW_MODIFIERS_PREVIEW
* Removed use of MOD_DPAINT_PREVIEW_READY in DynamicPaint code (seems unecessary, and if it was, should be of more general scope).
* Added eModifierTypeFlag_UsesPreview to ModifierTypeFlag, for modifiers that can generate some preview data.
* Added three new modifier funcs, to handle preview modifiers in draw code / mod stack.
* For weights preview: added the generic DM_update_weight_mcol func, which can update WEIGHT_MCOL layer with either a given array of weights (currently used by DynamicPaint only), or from current active vgroup(s).
So now, draw code is fully generic (i.e. no more modifier-type checking in it). Mod stack code is generic to some extent, but will need more work.
Modified Paths:
--------------
trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h
trunk/blender/source/blender/blenkernel/BKE_modifier.h
trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c
trunk/blender/source/blender/blenkernel/intern/dynamicpaint.c
trunk/blender/source/blender/blenkernel/intern/modifier.c
trunk/blender/source/blender/editors/space_view3d/drawmesh.c
trunk/blender/source/blender/editors/space_view3d/drawobject.c
trunk/blender/source/blender/editors/space_view3d/view3d_intern.h
trunk/blender/source/blender/makesdna/DNA_dynamicpaint_types.h
trunk/blender/source/blender/modifiers/intern/MOD_dynamicpaint.c
trunk/blender/source/blender/modifiers/intern/MOD_weightvgedit.c
trunk/blender/source/blender/modifiers/intern/MOD_weightvgmix.c
trunk/blender/source/blender/modifiers/intern/MOD_weightvgproximity.c
Modified: trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h 2012-01-22 17:26:56 UTC (rev 43609)
+++ trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h 2012-01-22 17:54:23 UTC (rev 43610)
@@ -538,6 +538,15 @@
float (**deformmats)[3][3], float (**deformcos)[3]);
void weight_to_rgb(float r_rgb[3], const float weight);
+/* Update the weight MCOL preview layer.
+ * If weights are NULL, use object's active vgroup(s).
+ * Else, weights must be an array of weight float values.
+ * If indices is NULL, it must be of numVerts length.
+ * Else, it must be of num length, as indices, which contains vertices' idx to apply weights to.
+ * (other vertices are assumed zero weight).
+ */
+void DM_update_weight_mcol(struct Object *ob, struct DerivedMesh *dm, int const draw_flag,
+ float *weights, int num, const int *indices);
/* convert layers requested by a GLSL material to actually available layers in
* the DerivedMesh, with both a pointer for arrays and an offset for editmesh */
Modified: trunk/blender/source/blender/blenkernel/BKE_modifier.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_modifier.h 2012-01-22 17:26:56 UTC (rev 43609)
+++ trunk/blender/source/blender/blenkernel/BKE_modifier.h 2012-01-22 17:54:23 UTC (rev 43610)
@@ -99,7 +99,10 @@
eModifierTypeFlag_Single = (1<<7),
/* Some modifier can't be added manually by user */
- eModifierTypeFlag_NoUserAdd = (1<<8)
+ eModifierTypeFlag_NoUserAdd = (1<<8),
+
+ /* For modifiers that use CD_WEIGHT_MCOL for preview. */
+ eModifierTypeFlag_UsesPreview = (1<<9)
} ModifierTypeFlag;
typedef void (*ObjectWalkFunc)(void *userData, struct Object *ob, struct Object **obpoin);
@@ -323,6 +326,7 @@
__attribute__ ((format (printf, 2, 3)))
#endif
;
+int modifier_isPreview(struct ModifierData *md);
void modifiers_foreachObjectLink(struct Object *ob,
ObjectWalkFunc walk,
@@ -349,6 +353,7 @@
int modifiers_usesArmature(struct Object *ob, struct bArmature *arm);
int modifiers_isCorrectableDeformed(struct Object *ob);
void modifier_freeTemporaryData(struct ModifierData *md);
+int modifiers_isPreview(struct Object *ob);
int modifiers_indexInObject(struct Object *ob, struct ModifierData *md);
@@ -362,6 +367,9 @@
struct ModifierData *md,
CustomDataMask dataMask,
int required_mode);
+struct ModifierData *modifiers_getLastPreview(struct Scene *scene,
+ struct ModifierData *md,
+ int required_mode);
struct ModifierData *modifiers_getVirtualModifierList(struct Object *ob);
/* ensure modifier correctness when changing ob->data */
Modified: trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c 2012-01-22 17:26:56 UTC (rev 43609)
+++ trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c 2012-01-22 17:54:23 UTC (rev 43610)
@@ -722,24 +722,23 @@
* note that we could save some memory and allocate RGB only but then we'd need to
* re-arrange the colors when copying to the face since MCol has odd ordering,
* so leave this as is - campbell */
-static unsigned char *calc_weightpaint_vert_array(Object *ob, int const draw_flag, ColorBand *coba)
+static unsigned char *calc_weightpaint_vert_array(Object *ob, DerivedMesh *dm, int const draw_flag, ColorBand *coba)
{
- Mesh *me = ob->data;
- unsigned char *wtcol_v = MEM_mallocN (sizeof(unsigned char) * me->totvert * 4, "weightmap_v");
+ MDeformVert *dv = DM_get_vert_data_layer(dm, CD_MDEFORMVERT);
+ int numVerts = dm->getNumVerts(dm);
+ unsigned char *wtcol_v = MEM_mallocN (sizeof(unsigned char) * numVerts * 4, "weightmap_v");
- if (me->dvert) {
+ if (dv) {
unsigned char *wc = wtcol_v;
- MDeformVert *dv= me->dvert;
unsigned int i;
- /* varisbles for multipaint */
+ /* variables for multipaint */
const int defbase_tot = BLI_countlist(&ob->defbase);
const int defbase_act = ob->actdef-1;
char *dg_flags = MEM_mallocN(defbase_tot * sizeof(char), __func__);
const int selected = get_selected_defgroups(ob, dg_flags, defbase_tot);
- /* const int unselected = defbase_tot - selected; */ /* UNUSED */
- for (i = me->totvert; i != 0; i--, wc += 4, dv++) {
+ for (i = numVerts; i != 0; i--, wc += 4, dv++) {
calc_weightpaint_vert_color(wc, dv, coba, defbase_tot, defbase_act, dg_flags, selected, draw_flag);
}
@@ -748,48 +747,94 @@
else {
int col_i;
weightpaint_color((unsigned char *)&col_i, coba, 0.0f);
- fill_vn_i((int *)wtcol_v, me->totvert, col_i);
+ fill_vn_i((int *)wtcol_v, numVerts, col_i);
}
return wtcol_v;
}
-static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag)
+/* return an array of vertex weight colors from given weights, caller must free.
+ *
+ * note that we could save some memory and allocate RGB only but then we'd need to
+ * re-arrange the colors when copying to the face since MCol has odd ordering,
+ * so leave this as is - campbell */
+static unsigned char *calc_colors_from_weights_array(const int num, float *weights)
{
+ unsigned char *wtcol_v = MEM_mallocN(sizeof(unsigned char) * num * 4, "weightmap_v");
+ unsigned char *wc = wtcol_v;
+ int i;
+
+ for (i = 0; i < num; i++, wc += 4, weights++)
+ weightpaint_color((unsigned char *) wc, NULL, *weights);
+
+ return wtcol_v;
+}
+
+void DM_update_weight_mcol(Object *ob, DerivedMesh *dm, int const draw_flag,
+ float *weights, int num, const int *indices)
+{
ColorBand *coba= stored_cb; /* warning, not a local var */
- Mesh *me = ob->data;
- unsigned char *wtcol_v = calc_weightpaint_vert_array(ob, draw_flag, coba);
- unsigned char *wtcol_f = MEM_mallocN (sizeof(unsigned char) * me->totface*4*4, "weightmap_f");
- unsigned char *wtcol_f_step = wtcol_f;
-
- MFace *mf = me->mface;
+ MFace *mf = dm->getFaceArray(dm);
+ int numFaces = dm->getNumFaces(dm);
+ int numVerts = dm->getNumVerts(dm);
+ unsigned char *wtcol_v;
+ unsigned char *wtcol_f = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
int i;
- for (i=0; i<me->totface; i++, mf++, wtcol_f_step += (4 * 4)) {
+ /* If no CD_WEIGHT_MCOL existed yet, add a new one! */
+ if (!wtcol_f)
+ wtcol_f = CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_CALLOC, NULL, numFaces);
+
+ if (wtcol_f) {
+ unsigned char *wtcol_f_step = wtcol_f;
+
+ /* Weights are given by caller. */
+ if (weights) {
+ float *w = weights;
+ /* If indices is not NULL, it means we do not have weights for all vertices,
+ * so we must create them (and set them to zero)... */
+ if(indices) {
+ w = MEM_callocN(sizeof(float)*numVerts, "Temp weight array DM_update_weight_mcol");
+ i = num;
+ while(i--)
+ w[indices[i]] = weights[i];
+ }
+
+ /* Convert float weights to colors. */
+ wtcol_v = calc_colors_from_weights_array(numVerts, w);
+
+ if(indices)
+ MEM_freeN(w);
+ }
+
+ /* No weights given, take them from active vgroup(s). */
+ else
+ wtcol_v = calc_weightpaint_vert_array(ob, dm, draw_flag, coba);
+
+ /* Now copy colors in all face verts. */
+ for (i = 0; i < numFaces; i++, mf++, wtcol_f_step += (4 * 4)) {
#if 0
- unsigned int fidx= mf->v4 ? 3:2;
+ unsigned int fidx= mf->v4 ? 3:2;
#else /* better zero out triangles 4th component. else valgrind complains when the buffer's copied */
- unsigned int fidx;
- if (mf->v4) {
- fidx = 3;
- }
- else {
- fidx = 2;
- *(int *)(&wtcol_f_step[3 * 4]) = 0;
- }
+ unsigned int fidx;
+ if (mf->v4) {
+ fidx = 3;
+ }
+ else {
+ fidx = 2;
+ *(int *)(&wtcol_f_step[3 * 4]) = 0;
+ }
#endif
- do {
- copy_v4_v4_char((char *)&wtcol_f_step[fidx * 4],
- (char *)&wtcol_v[4 * (*(&mf->v1 + fidx))]);
- } while (fidx--);
+ do {
+ copy_v4_v4_char((char *)&wtcol_f_step[fidx * 4],
+ (char *)&wtcol_v[4 * (*(&mf->v1 + fidx))]);
+ } while (fidx--);
+ }
+ MEM_freeN(wtcol_v);
}
-
- MEM_freeN(wtcol_v);
-
- CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol_f, dm->numFaceData);
}
/* new value for useDeform -1 (hack for the gameengine):
@@ -803,7 +848,7 @@
int needMapping, CustomDataMask dataMask, int index, int useCache)
{
Mesh *me = ob->data;
- ModifierData *firstmd, *md;
+ ModifierData *firstmd, *md, *previewmd = NULL;
LinkNode *datamasks, *curr;
CustomDataMask mask, nextmask, append_mask = 0;
float (*deformedVerts)[3] = NULL;
@@ -816,8 +861,17 @@
int has_multires = mmd != NULL, multires_applied = 0;
int sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt;
- int draw_flag= ((scene->toolsettings->multipaint ? CALC_WP_MULTIPAINT : 0) |
- (scene->toolsettings->auto_normalize ? CALC_WP_AUTO_NORMALIZE : 0));
+ const int draw_flag= ((scene->toolsettings->multipaint ? CALC_WP_MULTIPAINT : 0) |
+ (scene->toolsettings->auto_normalize ? CALC_WP_AUTO_NORMALIZE : 0));
+ /* Generic preview only in object mode! */
+ const int do_mod_mcol = (ob->mode == OB_MODE_OBJECT);
+#if 0 /* XXX Will re-enable this when we have global mod stack options. */
+ const int do_final_wmcol = (scene->toolsettings->weights_preview == WP_WPREVIEW_FINAL) && do_wmcol;
+#endif
+ const int do_final_wmcol = FALSE;
+ int do_init_wmcol = ((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT) && !do_final_wmcol);
+ /* XXX Same as above... For now, only weights preview in WPaint mode. */
+ const int do_mod_wmcol = do_init_wmcol;
if(mmd && !mmd->sculptlvl)
has_multires = 0;
@@ -842,6 +896,14 @@
datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode);
curr = datamasks;
+ if(do_mod_wmcol || do_mod_mcol) {
+ /* Find the last active modifier generating a preview, or NULL if none. */
+ /* XXX Currently, DPaint modifier just ignores this.
+ * Needs a stupid hack...
+ * The whole "modifier preview" thing has to be (re?)designed, anyway! */
+ previewmd = modifiers_getLastPreview(scene, md, required_mode);
+ }
+
if(deform_r) *deform_r = NULL;
*final_r = NULL;
@@ -997,8 +1059,8 @@
CDDM_calc_normals(dm);
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list