Add DNA and customdata entries for paint masks.
authorNicholas Bishop <nicholasbishop@gmail.com>
Thu, 10 May 2012 20:33:24 +0000 (20:33 +0000)
committerNicholas Bishop <nicholasbishop@gmail.com>
Thu, 10 May 2012 20:33:24 +0000 (20:33 +0000)
CD_PAINT_MASK is a layer of per-vertex floats for non-multires
meshes. Multires meshes use CD_GRID_PAINT_MASK, which is a layer of
per-loop GridPaintMask structures. GridPaintMask is similar to MDisp,
but contains an array of scalar floats.

Note: the GridPaintMask could be folded into MDisp, but this way
should be easier to add mask layers in the future (if we do fold
GridPaintMask into MDisp, the mask array should probably be an array
of arrays with a 'totmask' field so that mask layers can be easily
supported.)

Includes blenload read/write support for CD_PAINT_MASK and
CD_GRID_PAINT_MASK.

source/blender/blenkernel/intern/customdata.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/makesdna/DNA_customdata_types.h
source/blender/makesdna/DNA_meshdata_types.h

index a335d00c9a0d2d9aeb8804ea0b30576785c91e40..5eab6aeccef142dc3ae3d3c7120b058b9250cfdb 100644 (file)
@@ -565,6 +565,38 @@ static size_t layerFilesize_mdisps(CDataFile *UNUSED(cdf), void *data, int count
        return size;
 }
 
+static void layerCopy_grid_paint_mask(const void *source, void *dest, int count)
+{
+       int i;
+       const GridPaintMask *s = source;
+       GridPaintMask *d = dest;
+
+       for(i = 0; i < count; ++i) {
+               if(s[i].data) {
+                       d[i].data = MEM_dupallocN(s[i].data);
+                       d[i].level = s[i].level;
+               }
+               else {
+                       d[i].data = NULL;
+                       d[i].level = 0;
+               }
+               
+       }
+}
+
+static void layerFree_grid_paint_mask(void *data, int count, int UNUSED(size))
+{
+       int i;
+       GridPaintMask *gpm = data;
+
+       for(i = 0; i < count; ++i) {
+               if(gpm[i].data)
+                       MEM_freeN(gpm[i].data);
+               gpm[i].data = NULL;
+               gpm[i].level = 0;
+       }
+}
+
 /* --------- */
 static void layerCopyValue_mloopcol(void *source, void *dest)
 {
@@ -1059,7 +1091,11 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
 
 /* END BMESH ONLY */
 
-
+       /* 34: CD_PAINT_MASK */
+       {sizeof(float), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
+       /* 35: CD_GRID_PAINT_MASK */
+       {sizeof(GridPaintMask), "GridPaintMask", 1, NULL, layerCopy_grid_paint_mask,
+        layerFree_grid_paint_mask, NULL, NULL, NULL}
 };
 
 /* note, numbers are from trunk and need updating for bmesh */
@@ -1073,7 +1109,9 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
 
 /* BMESH ONLY */
        /* 25-29 */ "CDMPoly", "CDMLoop", "CDShapeKeyIndex", "CDShapeKey", "CDBevelWeight",
-       /* 30-32 */ "CDSubSurfCrease", "CDOrigSpaceLoop", "CDPreviewLoopCol"
+       /* 30-34 */ "CDSubSurfCrease", "CDOrigSpaceLoop", "CDPreviewLoopCol", "CDBMElemPyPtr", "CDPaintMask",
+       /*    35 */ "CDGridPaintMask"
+
 /* END BMESH ONLY */
 
 };
@@ -1086,12 +1124,14 @@ const CustomDataMask CD_MASK_MESH =
        CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL |
        CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS |
        CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MPOLY | CD_MASK_MLOOP |
-       CD_MASK_MTEXPOLY | CD_MASK_NORMAL | CD_MASK_RECAST;
+       CD_MASK_MTEXPOLY | CD_MASK_NORMAL | CD_MASK_RECAST | CD_MASK_PAINT_MASK |
+       CD_MASK_GRID_PAINT_MASK;
 const CustomDataMask CD_MASK_EDITMESH =
        CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MLOOPUV |
        CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_SHAPE_KEYINDEX |
        CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR |
-       CD_MASK_MDISPS | CD_MASK_SHAPEKEY | CD_MASK_RECAST;
+       CD_MASK_MDISPS | CD_MASK_SHAPEKEY | CD_MASK_RECAST | CD_MASK_PAINT_MASK |
+       CD_MASK_GRID_PAINT_MASK;
 const CustomDataMask CD_MASK_DERIVEDMESH =
        CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
        CD_MASK_MCOL | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_CLOTH_ORCO |
@@ -1101,7 +1141,9 @@ const CustomDataMask CD_MASK_DERIVEDMESH =
        CD_MASK_ORIGINDEX | CD_MASK_POLYINDEX;
 const CustomDataMask CD_MASK_BMESH = CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY |
        CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | 
-       CD_MASK_PROP_STR | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_MDISPS | CD_MASK_CREASE | CD_MASK_BWEIGHT | CD_MASK_RECAST;
+       CD_MASK_PROP_STR | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_MDISPS |
+       CD_MASK_CREASE | CD_MASK_BWEIGHT | CD_MASK_RECAST | CD_MASK_PAINT_MASK |
+       CD_MASK_GRID_PAINT_MASK;
 const CustomDataMask CD_MASK_FACECORNERS =
        CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV |
        CD_MASK_MLOOPCOL;
index 8c8066e9bd0e1bdb08fb215fc69ab867d380aa68..5bf2c8e53e25d971fcdebd0007f72f95adef543e 100644 (file)
@@ -3828,6 +3828,19 @@ static void direct_link_mdisps(FileData *fd, int count, MDisps *mdisps, int exte
        }
 }
 
+static void direct_link_grid_paint_mask(FileData *fd, int count, GridPaintMask *grid_paint_mask)
+{
+       if(grid_paint_mask) {
+               int i;
+
+               for(i = 0; i < count; ++i) {
+                       GridPaintMask *gpm = &grid_paint_mask[i];
+                       if(gpm->data)
+                               gpm->data = newdataadr(fd, gpm->data);
+               }
+       }
+}
+
 /*this isn't really a public api function, so prototyped here*/
 static void direct_link_customdata(FileData *fd, CustomData *data, int count)
 {
@@ -3854,6 +3867,8 @@ static void direct_link_customdata(FileData *fd, CustomData *data, int count)
                        layer->data = newdataadr(fd, layer->data);
                        if (layer->type == CD_MDISPS)
                                direct_link_mdisps(fd, count, layer->data, layer->flag & CD_FLAG_EXTERNAL);
+                       else if(layer->type == CD_GRID_PAINT_MASK)
+                               direct_link_grid_paint_mask(fd, count, layer->data);
                        i++;
                }
        }
index 91ce94ae6edde01ff2a440060d54dcdc2518fa32..27ecf25fa91175c01dab48a2bb75003d1a98f372 100644 (file)
@@ -152,6 +152,7 @@ Any case: direct data is ALWAYS after the lib block
 #include "BKE_node.h"
 #include "BKE_report.h"
 #include "BKE_sequencer.h"
+#include "BKE_subsurf.h"
 #include "BKE_utildefines.h"
 #include "BKE_modifier.h"
 #include "BKE_fcurve.h"
@@ -1654,6 +1655,24 @@ static void write_mdisps(WriteData *wd, int count, MDisps *mdlist, int external)
        }
 }
 
+static void write_grid_paint_mask(WriteData *wd, int count, GridPaintMask *grid_paint_mask)
+{
+       if(grid_paint_mask) {
+               int i;
+               
+               writestruct(wd, DATA, "GridPaintMask", count, grid_paint_mask);
+               for(i = 0; i < count; ++i) {
+                       GridPaintMask *gpm = &grid_paint_mask[i];
+                       if(gpm->data) {
+                               const int gridsize = ccg_gridsize(gpm->level);
+                               writedata(wd, DATA,
+                                                 sizeof(*gpm->data) * gridsize * gridsize,
+                                                 gpm->data);
+                       }
+               }
+       }
+}
+
 static void write_customdata(WriteData *wd, ID *id, int count, CustomData *data, int partial_type, int partial_count)
 {
        int i;
@@ -1676,6 +1695,13 @@ static void write_customdata(WriteData *wd, ID *id, int count, CustomData *data,
                else if (layer->type == CD_MDISPS) {
                        write_mdisps(wd, count, layer->data, layer->flag & CD_FLAG_EXTERNAL);
                }
+               else if (layer->type == CD_PAINT_MASK) {
+                       float *layer_data = layer->data;
+                       writedata(wd, DATA, sizeof(*layer_data) * count, layer_data);
+               }
+               else if (layer->type == CD_GRID_PAINT_MASK) {
+                       write_grid_paint_mask(wd, count, layer->data);
+               }
                else {
                        CustomData_file_write_info(layer->type, &structname, &structnum);
                        if (structnum) {
index 9898f9715a0731bb5e8a666b2cb24bfb8409987b..5792953fe498d472d0a6855490c749668818d1f8 100644 (file)
@@ -63,7 +63,7 @@ typedef struct CustomDataExternal {
  * layers, each with a data type (e.g. MTFace, MDeformVert, etc.). */
 typedef struct CustomData {
        CustomDataLayer *layers;      /* CustomDataLayers, ordered by type */
-       int typemap[34];              /* runtime only! - maps types to indices of first layer of that type,
+       int typemap[36];              /* runtime only! - maps types to indices of first layer of that type,
                                       * MUST be >= CD_NUMTYPES, but we cant use a define here.
                                       * Correct size is ensured in CustomData_update_typemap assert() */
 
@@ -112,7 +112,10 @@ typedef struct CustomData {
 #define CD_BM_ELEM_PYPTR       33
 /* BMESH ONLY END */
 
-#define CD_NUMTYPES            34
+#define CD_PAINT_MASK  34
+#define CD_GRID_PAINT_MASK     35
+
+#define CD_NUMTYPES            36
 
 /* Bits for CustomDataMask */
 #define CD_MASK_MVERT          (1 << CD_MVERT)
@@ -151,6 +154,9 @@ typedef struct CustomData {
 #define CD_MASK_BM_ELEM_PYPTR (1LL << CD_BM_ELEM_PYPTR)
 /* BMESH ONLY END */
 
+#define CD_MASK_PAINT_MASK             (1LL << CD_PAINT_MASK)
+#define CD_MASK_GRID_PAINT_MASK        (1LL << CD_GRID_PAINT_MASK)
+
 /* CustomData.flag */
 
 /* indicates layer should not be copied by CustomData_from_template or
index a0806481aea699f562620cc7a9d7eae36a26ec1f..ff23b37ad0cba92db75233b5cf0d5ab16afc8882 100644 (file)
@@ -247,6 +247,16 @@ typedef struct MRecast {
        int             i;
 } MRecast;
 
+typedef struct GridPaintMask {
+       /* The data array contains gridsize*gridsize elements */
+       float *data;
+
+       /* The maximum multires level associated with this grid */
+       unsigned int level;
+
+       int pad;
+} GridPaintMask;
+
 /* mvert->flag (1=SELECT) */
 #define ME_SPHERETEST          2
 #define ME_VERT_TMP_TAG                4