Merged changes in the trunk up to revision 53584.
[blender.git] / source / blender / blenkernel / BKE_DerivedMesh.h
index 87ba2092437f9e5399ef70f55a8adfbf73276f15..ed90c63d9493b6c4e2540872b6bc849cb43f5b66 100644 (file)
 #ifndef __BKE_DERIVEDMESH_H__
 #define __BKE_DERIVEDMESH_H__
 
-/*
+/**
  * Basic design of the DerivedMesh system:
  *
  * DerivedMesh is a common set of interfaces for mesh systems.
  *
- * There are three main mesh data structures in Blender: Mesh, CDDM, and BMesh.
+ * There are three main mesh data structures in Blender:
+ * #Mesh, #CDDerivedMesh and #BMesh.
+ *
  * These, and a few others, all implement DerivedMesh interfaces, 
  * which contains unified drawing interfaces, a few utility interfaces, 
  * and a bunch of read-only interfaces intended mostly for conversion from 
  *       as it is and stick with using BMesh and CDDM.
  */
 
-
 #include "DNA_customdata_types.h"
 #include "DNA_meshdata_types.h"
 
 #include "BKE_customdata.h"
 #include "BKE_bvhutils.h"
 
+struct CCGElem;
+struct CCGKey;
 struct MVert;
 struct MEdge;
 struct MFace;
@@ -98,14 +101,14 @@ struct PBVH;
 #define SUB_ELEMS_FACE 50
 
 /*
- * Note: all mface interfaces now officially operate on tesselated data.
+ * Note: all mface interfaces now officially operate on tessellated data.
  *       Also, the mface origindex layer indexes mpolys, not mfaces.
  */
 
-typedef struct DMGridData {
+typedef struct DMCoNo {
        float co[3];
        float no[3];
-} DMGridData;
+} DMCoNo;
 
 typedef struct DMGridAdjacency {
        int index[4];
@@ -147,9 +150,19 @@ typedef enum DMDrawFlag {
        DM_DRAW_ALWAYS_SMOOTH = 2
 } DMDrawFlag;
 
+typedef enum DMDirtyFlag {
+       /* dm has valid tessellated faces, but tessellated CDDATA need to be updated. */
+       DM_DIRTY_TESS_CDLAYERS = 1 << 0,
+       /* One of the MCOL layers have been updated, force updating of GPUDrawObject's colors buffer.
+        * This is necessary with modern, VBO draw code, as e.g. in vpaint mode me->mcol may be updated
+        * without actually rebuilding dm (hence by defautl keeping same GPUDrawObject, and same colors
+        * buffer, which prevents update during a stroke!). */
+       DM_DIRTY_MCOL_UPDATE_DRAW = 1 << 1,
+} DMDirtyFlag;
+
 typedef struct DerivedMesh DerivedMesh;
 struct DerivedMesh {
-       /* Private DerivedMesh data, only for internal DerivedMesh use */
+       /** Private DerivedMesh data, only for internal DerivedMesh use */
        CustomData vertData, edgeData, faceData, loopData, polyData;
        int numVertData, numEdgeData, numTessFaceData, numLoopData, numPolyData;
        int needsFree; /* checked on ->release, is set to 0 for cached results */
@@ -158,11 +171,12 @@ struct DerivedMesh {
        struct GPUDrawObject *drawObject;
        DerivedMeshType type;
        float auto_bump_scale;
+       DMDirtyFlag dirty;
 
-       /* calculate vert and face normals */
+       /** Calculate vert and face normals */
        void (*calcNormals)(DerivedMesh *dm);
 
-       /* recalculates mesh tessellation */
+       /** Recalculates mesh tessellation */
        void (*recalcTessellation)(DerivedMesh *dm);
 
        /* Misc. Queries */
@@ -174,7 +188,7 @@ struct DerivedMesh {
        int (*getNumLoops)(DerivedMesh *dm);
        int (*getNumPolys)(DerivedMesh *dm);
 
-       /* copy a single vert/edge/tesselated face from the derived mesh into
+       /** Copy a single vert/edge/tessellated face from the derived mesh into
         * *{vert/edge/face}_r. note that the current implementation
         * of this function can be quite slow, iterating over all
         * elements (editmesh)
@@ -183,18 +197,18 @@ struct DerivedMesh {
        void (*getEdge)(DerivedMesh *dm, int index, struct MEdge *edge_r);
        void (*getTessFace)(DerivedMesh *dm, int index, struct MFace *face_r);
 
-       /* return a pointer to the entire array of verts/edges/face from the
+       /** Return a pointer to the entire array of verts/edges/face from the
         * derived mesh. if such an array does not exist yet, it will be created,
         * and freed on the next ->release(). consider using getVert/Edge/Face if
         * you are only interested in a few verts/edges/faces.
         */
-       struct MVert *(*getVertArray)(DerivedMesh *dm);
-       struct MEdge *(*getEdgeArray)(DerivedMesh *dm);
-       struct MFace *(*getTessFaceArray)(DerivedMesh *dm);
-       struct MLoop *(*getLoopArray)(DerivedMesh *dm);
-       struct MPoly *(*getPolyArray)(DerivedMesh *dm);
+       struct MVert *(*getVertArray)(DerivedMesh * dm);
+       struct MEdge *(*getEdgeArray)(DerivedMesh * dm);
+       struct MFace *(*getTessFaceArray)(DerivedMesh * dm);
+       struct MLoop *(*getLoopArray)(DerivedMesh * dm);
+       struct MPoly *(*getPolyArray)(DerivedMesh * dm);
 
-       /* copy all verts/edges/faces from the derived mesh into
+       /** Copy all verts/edges/faces from the derived mesh into
         * *{vert/edge/face}_r (must point to a buffer large enough)
         */
        void (*copyVertArray)(DerivedMesh *dm, struct MVert *vert_r);
@@ -203,127 +217,130 @@ struct DerivedMesh {
        void (*copyLoopArray)(DerivedMesh *dm, struct MLoop *loop_r);
        void (*copyPolyArray)(DerivedMesh *dm, struct MPoly *poly_r);
 
-       /* return a copy of all verts/edges/faces from the derived mesh
+       /** Return a copy of all verts/edges/faces from the derived mesh
         * it is the caller's responsibility to free the returned pointer
         */
-       struct MVert *(*dupVertArray)(DerivedMesh *dm);
-       struct MEdge *(*dupEdgeArray)(DerivedMesh *dm);
-       struct MFace *(*dupTessFaceArray)(DerivedMesh *dm);
-       struct MLoop *(*dupLoopArray)(DerivedMesh *dm);
-       struct MPoly *(*dupPolyArray)(DerivedMesh *dm);
+       struct MVert *(*dupVertArray)(DerivedMesh * dm);
+       struct MEdge *(*dupEdgeArray)(DerivedMesh * dm);
+       struct MFace *(*dupTessFaceArray)(DerivedMesh * dm);
+       struct MLoop *(*dupLoopArray)(DerivedMesh * dm);
+       struct MPoly *(*dupPolyArray)(DerivedMesh * dm);
 
-       /* return a pointer to a single element of vert/edge/face custom data
+       /** Return a pointer to a single element of vert/edge/face custom data
         * from the derived mesh (this gives a pointer to the actual data, not
         * a copy)
         */
-       void *(*getVertData)(DerivedMesh *dm, int index, int type);
-       void *(*getEdgeData)(DerivedMesh *dm, int index, int type);
-       void *(*getTessFaceData)(DerivedMesh *dm, int index, int type);
+       void *(*getVertData)(DerivedMesh * dm, int index, int type);
+       void *(*getEdgeData)(DerivedMesh * dm, int index, int type);
+       void *(*getTessFaceData)(DerivedMesh * dm, int index, int type);
+       void *(*getPolyData)(DerivedMesh * dm, int index, int type);
 
-       /* return a pointer to the entire array of vert/edge/face custom data
+       /** Return a pointer to the entire array of vert/edge/face custom data
         * from the derived mesh (this gives a pointer to the actual data, not
         * a copy)
         */
-       void *(*getVertDataArray)(DerivedMesh *dm, int type);
-       void *(*getEdgeDataArray)(DerivedMesh *dm, int type);
-       void *(*getTessFaceDataArray)(DerivedMesh *dm, int type);
-       
-       /* retrieves the base CustomData structures for 
+       void *(*getVertDataArray)(DerivedMesh * dm, int type);
+       void *(*getEdgeDataArray)(DerivedMesh * dm, int type);
+       void *(*getTessFaceDataArray)(DerivedMesh * dm, int type);
+       void *(*getPolyDataArray)(DerivedMesh * dm, int type);
+
+       /** Retrieves the base CustomData structures for
         * verts/edges/tessfaces/loops/facdes*/
-       CustomData *(*getVertDataLayout)(DerivedMesh *dm);
-       CustomData *(*getEdgeDataLayout)(DerivedMesh *dm);
-       CustomData *(*getTessFaceDataLayout)(DerivedMesh *dm);
-       CustomData *(*getLoopDataLayout)(DerivedMesh *dm);
-       CustomData *(*getPolyDataLayout)(DerivedMesh *dm);
+       CustomData *(*getVertDataLayout)(DerivedMesh * dm);
+       CustomData *(*getEdgeDataLayout)(DerivedMesh * dm);
+       CustomData *(*getTessFaceDataLayout)(DerivedMesh * dm);
+       CustomData *(*getLoopDataLayout)(DerivedMesh * dm);
+       CustomData *(*getPolyDataLayout)(DerivedMesh * dm);
        
-       /*copies all customdata for an element source into dst at index dest*/
+       /** Copies all customdata for an element source into dst at index dest */
        void (*copyFromVertCData)(DerivedMesh *dm, int source, CustomData *dst, int dest);
        void (*copyFromEdgeCData)(DerivedMesh *dm, int source, CustomData *dst, int dest);
        void (*copyFromFaceCData)(DerivedMesh *dm, int source, CustomData *dst, int dest);
        
-       /* optional grid access for subsurf */
+       /** Optional grid access for subsurf */
        int (*getNumGrids)(DerivedMesh *dm);
        int (*getGridSize)(DerivedMesh *dm);
-       DMGridData **(*getGridData)(DerivedMesh *dm);
-       DMGridAdjacency *(*getGridAdjacency)(DerivedMesh *dm);
-       int *(*getGridOffset)(DerivedMesh *dm);
-       DMFlagMat *(*getGridFlagMats)(DerivedMesh *dm);
+       struct CCGElem **(*getGridData)(DerivedMesh * dm);
+       DMGridAdjacency *(*getGridAdjacency)(DerivedMesh * dm);
+       int *(*getGridOffset)(DerivedMesh * dm);
+       void (*getGridKey)(DerivedMesh *dm, struct CCGKey *key);
+       DMFlagMat *(*getGridFlagMats)(DerivedMesh * dm);
+       unsigned int **(*getGridHidden)(DerivedMesh * dm);
        
 
-       /* Iterate over each mapped vertex in the derived mesh, calling the
+       /** Iterate over each mapped vertex in the derived mesh, calling the
         * given function with the original vert and the mapped vert's new
         * coordinate and normal. For historical reasons the normal can be
         * passed as a float or short array, only one should be non-NULL.
         */
-       void (*foreachMappedVert)(
-                                                 DerivedMesh *dm,
-                                                 void (*func)(void *userData, int index, float *co,
-                                                                          float *no_f, short *no_s),
-                                                 void *userData);
+       void (*foreachMappedVert)(DerivedMesh *dm,
+                                 void (*func)(void *userData, int index, const float co[3],
+                                              const float no_f[3], const short no_s[3]),
+                                 void *userData);
 
-       /* Iterate over each mapped edge in the derived mesh, calling the
+       /** Iterate over each mapped edge in the derived mesh, calling the
         * given function with the original edge and the mapped edge's new
         * coordinates.
         */
        void (*foreachMappedEdge)(DerivedMesh *dm,
-                                                         void (*func)(void *userData, int index,
-                                                                                  float *v0co, float *v1co),
-                                                         void *userData);
+                                 void (*func)(void *userData, int index,
+                                              const float v0co[3], const float v1co[3]),
+                                 void *userData);
 
-       /* Iterate over each mapped face in the derived mesh, calling the
+       /** Iterate over each mapped face in the derived mesh, calling the
         * given function with the original face and the mapped face's (or
         * faces') center and normal.
         */
        void (*foreachMappedFaceCenter)(DerivedMesh *dm,
-                                                                       void (*func)(void *userData, int index,
-                                                                                                float *cent, float *no),
-                                                                       void *userData);
+                                       void (*func)(void *userData, int index,
+                                                    const float cent[3], const float no[3]),
+                                       void *userData);
 
-       /* Iterate over all vertex points, calling DO_MINMAX with given args.
+       /** Iterate over all vertex points, calling DO_MINMAX with given args.
         *
         * Also called in Editmode
         */
        void (*getMinMax)(DerivedMesh *dm, float min_r[3], float max_r[3]);
 
-       /* Direct Access Operations */
-       /*  o Can be undefined */
-       /*  o Must be defined for modifiers that only deform however */
+       /** Direct Access Operations
+        * - Can be undefined
+        * - Must be defined for modifiers that only deform however */
 
-       /* Get vertex location, undefined if index is not valid */
+       /** Get vertex location, undefined if index is not valid */
        void (*getVertCo)(DerivedMesh *dm, int index, float co_r[3]);
 
-       /* Fill the array (of length .getNumVerts()) with all vertex locations */
+       /** Fill the array (of length .getNumVerts()) with all vertex locations */
        void (*getVertCos)(DerivedMesh *dm, float (*cos_r)[3]);
 
-       /* Get smooth vertex normal, undefined if index is not valid */
+       /** Get smooth vertex normal, undefined if index is not valid */
        void (*getVertNo)(DerivedMesh *dm, int index, float no_r[3]);
 
-       /* Get a map of vertices to faces
+       /** Get a map of vertices to faces
         */
-       struct ListBase *(*getPolyMap)(struct Object *ob, DerivedMesh *dm);
+       const struct MeshElemMap *(*getPolyMap)(struct Object *ob, DerivedMesh *dm);
 
-       /* Get the BVH used for paint modes
+       /** Get the BVH used for paint modes
         */
        struct PBVH *(*getPBVH)(struct Object *ob, DerivedMesh *dm);
 
        /* Drawing Operations */
 
-       /* Draw all vertices as bgl points (no options) */
+       /** Draw all vertices as bgl points (no options) */
        void (*drawVerts)(DerivedMesh *dm);
 
-       /* Draw edges in the UV mesh (if exists) */
+       /** Draw edges in the UV mesh (if exists) */
        void (*drawUVEdges)(DerivedMesh *dm);
 
-       /* Draw all edges as lines (no options) 
+       /** Draw all edges as lines (no options)
         *
         * Also called for *final* editmode DerivedMeshes
         */
        void (*drawEdges)(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges);
        
-       /* Draw all loose edges (edges w/ no adjoining faces) */
+       /** Draw all loose edges (edges w/ no adjoining faces) */
        void (*drawLooseEdges)(DerivedMesh *dm);
 
-       /* Draw all faces
+       /** Draw all faces
         *  o Set face normal or vertex normal based on inherited face flag
         *  o Use inherited face material index to call setMaterial
         *  o Only if setMaterial returns true
@@ -331,26 +348,26 @@ struct DerivedMesh {
         * Also called for *final* editmode DerivedMeshes
         */
        void (*drawFacesSolid)(DerivedMesh *dm, float (*partial_redraw_planes)[4],
-                                                  int fast, DMSetMaterial setMaterial);
+                              int fast, DMSetMaterial setMaterial);
 
-       /* Draw all faces using MTFace 
-        *  o Drawing options too complicated to enumerate, look at code.
+       /** Draw all faces using MTFace
+        * - Drawing options too complicated to enumerate, look at code.
         */
        void (*drawFacesTex)(DerivedMesh *dm,
                             DMSetDrawOptionsTex setDrawOptions,
-                                                DMCompareDrawOptions compareDrawOptions,
-                                                void *userData);
+                            DMCompareDrawOptions compareDrawOptions,
+                            void *userData);
 
-       /* Draw all faces with GLSL materials
+       /** Draw all faces with GLSL materials
         *  o setMaterial is called for every different material nr
         *  o Only if setMaterial returns true
         */
        void (*drawFacesGLSL)(DerivedMesh *dm, DMSetMaterial setMaterial);
 
-       /* Draw mapped faces (no color, or texture)
-        *  o Only if !setDrawOptions or
-        *    setDrawOptions(userData, mapped-face-index, drawSmooth_r)
-        *    returns true
+       /** Draw mapped faces (no color, or texture)
+        * - Only if !setDrawOptions or
+        *   setDrawOptions(userData, mapped-face-index, drawSmooth_r)
+        *   returns true
         *
         * If drawSmooth is set to true then vertex normals should be set and
         * glShadeModel called with GL_SMOOTH. Otherwise the face normal should
@@ -361,105 +378,104 @@ struct DerivedMesh {
         * smooth shaded.
         */
        void (*drawMappedFaces)(DerivedMesh *dm,
-                                                       DMSetDrawOptions setDrawOptions,
-                                                       DMSetMaterial setMaterial,
-                                                       DMCompareDrawOptions compareDrawOptions,
-                                                       void *userData,
-                                                       DMDrawFlag flag);
-
-       /* Draw mapped faces using MTFace 
-        *  o Drawing options too complicated to enumerate, look at code.
+                               DMSetDrawOptions setDrawOptions,
+                               DMSetMaterial setMaterial,
+                               DMCompareDrawOptions compareDrawOptions,
+                               void *userData,
+                               DMDrawFlag flag);
+
+       /** Draw mapped faces using MTFace
+        * - Drawing options too complicated to enumerate, look at code.
         */
        void (*drawMappedFacesTex)(DerivedMesh *dm,
-                                                          DMSetDrawOptions setDrawOptions,
-                                                          DMCompareDrawOptions compareDrawOptions,
-                                                          void *userData);
-
-       /* Draw mapped faces with GLSL materials
-        *  o setMaterial is called for every different material nr
-        *  o setDrawOptions is called for every face
-        *  o Only if setMaterial and setDrawOptions return true
+                                  DMSetDrawOptions setDrawOptions,
+                                  DMCompareDrawOptions compareDrawOptions,
+                                  void *userData);
+
+       /** Draw mapped faces with GLSL materials
+        * - setMaterial is called for every different material nr
+        * - setDrawOptions is called for every face
+        * - Only if setMaterial and setDrawOptions return true
         */
        void (*drawMappedFacesGLSL)(DerivedMesh *dm,
-               DMSetMaterial setMaterial,
-               DMSetDrawOptions setDrawOptions,
-               void *userData);
+                                   DMSetMaterial setMaterial,
+                                   DMSetDrawOptions setDrawOptions,
+                                   void *userData);
 
-       /* Draw mapped edges as lines
-        *  o Only if !setDrawOptions or setDrawOptions(userData, mapped-edge)
-        *    returns true
+       /** Draw mapped edges as lines
+        * - Only if !setDrawOptions or setDrawOptions(userData, mapped-edge)
+        *   returns true
         */
        void (*drawMappedEdges)(DerivedMesh *dm,
-                                                       DMSetDrawOptions setDrawOptions,
-                                                       void *userData);
+                               DMSetDrawOptions setDrawOptions,
+                               void *userData);
 
-       /* Draw mapped edges as lines with interpolation values
-        *  o Only if !setDrawOptions or
-        *    setDrawOptions(userData, mapped-edge, mapped-v0, mapped-v1, t)
-        *    returns true
+       /** Draw mapped edges as lines with interpolation values
+        * - Only if !setDrawOptions or
+        *   setDrawOptions(userData, mapped-edge, mapped-v0, mapped-v1, t)
+        *   returns true
         *
         * NOTE: This routine is optional!
         */
        void (*drawMappedEdgesInterp)(DerivedMesh *dm, 
-                                                                 DMSetDrawOptions setDrawOptions,
-                                                                 DMSetDrawInterpOptions setDrawInterpOptions,
-                                                                 void *userData);
+                                     DMSetDrawOptions setDrawOptions,
+                                     DMSetDrawInterpOptions setDrawInterpOptions,
+                                     void *userData);
 
-       /* Draw all faces with materials
-        *  o setMaterial is called for every different material nr
-        *  o setFace is called to verify if a face must be hidden
+       /** Draw all faces with materials
+        * - setMaterial is called for every different material nr
+        * - setFace is called to verify if a face must be hidden
         */
        void (*drawMappedFacesMat)(DerivedMesh *dm,
-               void (*setMaterial)(void *userData, int, void *attribs),
-               int (*setFace)(void *userData, int index), void *userData);
+                                  void (*setMaterial)(void *userData, int, void *attribs),
+                                  int (*setFace)(void *userData, int index), void *userData);
 
-       /* Release reference to the DerivedMesh. This function decides internally
+       /** Release reference to the DerivedMesh. This function decides internally
         * if the DerivedMesh will be freed, or cached for later use. */
        void (*release)(DerivedMesh *dm);
 };
 
-/* utility function to initialize a DerivedMesh's function pointers to
+/** utility function to initialize a DerivedMesh's function pointers to
  * the default implementation (for those functions which have a default)
  */
 void DM_init_funcs(DerivedMesh *dm);
 
-/* utility function to initialize a DerivedMesh for the desired number
+/** utility function to initialize a DerivedMesh for the desired number
  * of vertices, edges and faces (doesn't allocate memory for them, just
  * sets up the custom data layers)
  */
 void DM_init(DerivedMesh *dm, DerivedMeshType type, int numVerts, int numEdges, 
              int numFaces, int numLoops, int numPolys);
 
-/* utility function to initialize a DerivedMesh for the desired number
+/** utility function to initialize a DerivedMesh for the desired number
  * of vertices, edges and faces, with a layer setup copied from source
  */
 void DM_from_template(DerivedMesh *dm, DerivedMesh *source,
-                         DerivedMeshType type,
-                         int numVerts, int numEdges, int numFaces,
-                     int numLoops, int numPolys);
+                      DerivedMeshType type,
+                      int numVerts, int numEdges, int numFaces,
+                      int numLoops, int numPolys);
 
-/* utility function to release a DerivedMesh's layers
+/** utility function to release a DerivedMesh's layers
  * returns 1 if DerivedMesh has to be released by the backend, 0 otherwise
  */
 int DM_release(DerivedMesh *dm);
 
-/* utility function to convert a DerivedMesh to a Mesh
+/** utility function to convert a DerivedMesh to a Mesh
  */
 void DM_to_mesh(DerivedMesh *dm, struct Mesh *me, struct Object *ob);
 
-struct BMEditMesh *DM_to_editbmesh(struct Object *ob, struct DerivedMesh *dm,
-                                   struct BMEditMesh *existing, int do_tesselate);
+struct BMEditMesh *DM_to_editbmesh(struct DerivedMesh *dm,
+                                   struct BMEditMesh *existing, int do_tessellate);
 
 /* conversion to bmesh only */
 void          DM_to_bmesh_ex(struct DerivedMesh *dm, struct BMesh *bm);
-struct BMesh *DM_to_bmesh(struct Object *ob, struct DerivedMesh *dm);
+struct BMesh *DM_to_bmesh(struct DerivedMesh *dm);
 
 
-/* utility function to convert a DerivedMesh to a shape key block 
- */
+/** Utility function to convert a DerivedMesh to a shape key block */
 void DM_to_meshkey(DerivedMesh *dm, struct Mesh *me, struct KeyBlock *kb);
 
-/* set the CD_FLAG_NOCOPY flag in custom data layers where the mask is
+/** set the CD_FLAG_NOCOPY flag in custom data layers where the mask is
  * zero for the layer type, so only layer types specified by the mask
  * will be copied
  */
@@ -489,6 +505,7 @@ void DM_add_poly_layer(struct DerivedMesh *dm, int type, int alloctype,
 void *DM_get_vert_data(struct DerivedMesh *dm, int index, int type);
 void *DM_get_edge_data(struct DerivedMesh *dm, int index, int type);
 void *DM_get_tessface_data(struct DerivedMesh *dm, int index, int type);
+void *DM_get_poly_data(struct DerivedMesh *dm, int index, int type);
 
 /* custom data layer access functions
  * return pointer to first data layer which matches type (a flat array)
@@ -514,15 +531,15 @@ void DM_set_tessface_data(struct DerivedMesh *dm, int index, int type, void *dat
  * these copy all layers for which the CD_FLAG_NOCOPY flag is not set
  */
 void DM_copy_vert_data(struct DerivedMesh *source, struct DerivedMesh *dest,
-                                          int source_index, int dest_index, int count);
+                       int source_index, int dest_index, int count);
 void DM_copy_edge_data(struct DerivedMesh *source, struct DerivedMesh *dest,
-                                          int source_index, int dest_index, int count);
-void DM_copy_tessface_data(struct DerivedMesh *source, struct DerivedMesh *dest,
                        int source_index, int dest_index, int count);
+void DM_copy_tessface_data(struct DerivedMesh *source, struct DerivedMesh *dest,
+                           int source_index, int dest_index, int count);
 void DM_copy_loop_data(struct DerivedMesh *source, struct DerivedMesh *dest,
                        int source_index, int dest_index, int count);
 void DM_copy_poly_data(struct DerivedMesh *source, struct DerivedMesh *dest,
-                                          int source_index, int dest_index, int count);
+                       int source_index, int dest_index, int count);
 
 /* custom data free functions
  * free count elements, starting at index
@@ -539,15 +556,17 @@ void DM_DupPolys(DerivedMesh *source, DerivedMesh *target);
 
 void DM_ensure_tessface(DerivedMesh *dm);
 
-/* interpolates vertex data from the vertices indexed by src_indices in the
+void DM_update_tessface_data(DerivedMesh *dm);
+
+/** interpolates vertex data from the vertices indexed by src_indices in the
  * source mesh using the given weights and stores the result in the vertex
  * indexed by dest_index in the dest mesh
  */
 void DM_interp_vert_data(struct DerivedMesh *source, struct DerivedMesh *dest,
-                                                int *src_indices, float *weights,
-                                                int count, int dest_index);
+                         int *src_indices, float *weights,
+                         int count, int dest_index);
 
-/* interpolates edge data from the edges indexed by src_indices in the
+/** interpolates edge data from the edges indexed by src_indices in the
  * source mesh using the given weights and stores the result in the edge indexed
  * by dest_index in the dest mesh.
  * if weights is NULL, all weights default to 1.
@@ -556,11 +575,11 @@ void DM_interp_vert_data(struct DerivedMesh *source, struct DerivedMesh *dest,
  */
 typedef float EdgeVertWeight[SUB_ELEMS_EDGE][SUB_ELEMS_EDGE];
 void DM_interp_edge_data(struct DerivedMesh *source, struct DerivedMesh *dest,
-                                                int *src_indices,
-                                                float *weights, EdgeVertWeight *vert_weights,
-                                                int count, int dest_index);
+                         int *src_indices,
+                         float *weights, EdgeVertWeight *vert_weights,
+                         int count, int dest_index);
 
-/* interpolates face data from the faces indexed by src_indices in the
+/** interpolates face data from the faces indexed by src_indices in the
  * source mesh using the given weights and stores the result in the face indexed
  * by dest_index in the dest mesh.
  * if weights is NULL, all weights default to 1.
@@ -569,9 +588,9 @@ void DM_interp_edge_data(struct DerivedMesh *source, struct DerivedMesh *dest,
  */
 typedef float FaceVertWeight[SUB_ELEMS_FACE][SUB_ELEMS_FACE];
 void DM_interp_tessface_data(struct DerivedMesh *source, struct DerivedMesh *dest,
-                                                int *src_indices,
-                                                float *weights, FaceVertWeight *vert_weights,
-                                                int count, int dest_index);
+                             int *src_indices,
+                             float *weights, FaceVertWeight *vert_weights,
+                             int count, int dest_index);
 
 void DM_swap_tessface_data(struct DerivedMesh *dm, int index, const int *corner_indices);
 
@@ -586,62 +605,62 @@ void DM_interp_poly_data(struct DerivedMesh *source, struct DerivedMesh *dest,
 /* Temporary? A function to give a colorband to derivedmesh for vertexcolor ranges */
 void vDM_ColorBand_store(struct ColorBand *coba);
 
-/* Simple function to get me->totvert amount of vertices/normals,
+/** Simple function to get me->totvert amount of vertices/normals,
  * correctly deformed and subsurfered. Needed especially when vertexgroups are involved.
  * In use now by vertex/weight paint and particles */
-float *mesh_get_mapped_verts_nors(struct Scene *scene, struct Object *ob);
+DMCoNo *mesh_get_mapped_verts_nors(struct Scene *scene, struct Object *ob);
 
-       /* */
+/* */
 DerivedMesh *mesh_get_derived_final(struct Scene *scene, struct Object *ob,
-                                                                       CustomDataMask dataMask);
+                                    CustomDataMask dataMask);
 DerivedMesh *mesh_get_derived_deform(struct Scene *scene, struct Object *ob,
-                                                                        CustomDataMask dataMask);
+                                     CustomDataMask dataMask);
 
 DerivedMesh *mesh_create_derived_for_modifier(struct Scene *scene, struct Object *ob,
-                                                                                         struct ModifierData *md, int build_shapekey_layers);
+                                              struct ModifierData *md, int build_shapekey_layers);
 
 DerivedMesh *mesh_create_derived_render(struct Scene *scene, struct Object *ob,
-                                                                               CustomDataMask dataMask);
+                                        CustomDataMask dataMask);
 
 DerivedMesh *getEditDerivedBMesh(struct BMEditMesh *em, struct Object *ob,
-                                           float (*vertexCos)[3]);
+                                 float (*vertexCos)[3]);
 
 DerivedMesh *mesh_create_derived_index_render(struct Scene *scene, struct Object *ob, CustomDataMask dataMask, int index);
 
-               /* same as above but wont use render settings */
+/* same as above but wont use render settings */
 DerivedMesh *mesh_create_derived(struct Mesh *me, struct Object *ob, float (*vertCos)[3]);
 DerivedMesh *mesh_create_derived_view(struct Scene *scene, struct Object *ob,
-                                                                         CustomDataMask dataMask);
+                                      CustomDataMask dataMask);
 DerivedMesh *mesh_create_derived_no_deform(struct Scene *scene, struct Object *ob,
-                                                                                  float (*vertCos)[3],
-                                                                                  CustomDataMask dataMask);
+                                           float (*vertCos)[3],
+                                           CustomDataMask dataMask);
 DerivedMesh *mesh_create_derived_no_deform_render(struct Scene *scene, struct Object *ob,
-                                                                                                 float (*vertCos)[3],
-                                                                                                 CustomDataMask dataMask);
+                                                  float (*vertCos)[3],
+                                                  CustomDataMask dataMask);
 /* for gameengine */
 DerivedMesh *mesh_create_derived_no_virtual(struct Scene *scene, struct Object *ob, float (*vertCos)[3],
-                                                                                       CustomDataMask dataMask);
+                                            CustomDataMask dataMask);
 DerivedMesh *mesh_create_derived_physics(struct Scene *scene, struct Object *ob, float (*vertCos)[3],
-                                                                                       CustomDataMask dataMask);
+                                         CustomDataMask dataMask);
 
 DerivedMesh *editbmesh_get_derived_base(struct Object *, struct BMEditMesh *em);
 DerivedMesh *editbmesh_get_derived_cage(struct Scene *scene, struct Object *, 
-                                                                          struct BMEditMesh *em, CustomDataMask dataMask);
+                                        struct BMEditMesh *em, CustomDataMask dataMask);
 DerivedMesh *editbmesh_get_derived_cage_and_final(struct Scene *scene, struct Object *, 
-                                                struct BMEditMesh *em, DerivedMesh **final_r,
-                                                                                                CustomDataMask dataMask);
+                                                  struct BMEditMesh *em, DerivedMesh **final_r,
+                                                  CustomDataMask dataMask);
 float (*editbmesh_get_vertex_cos(struct BMEditMesh *em, int *numVerts_r))[3];
 int editbmesh_modifier_is_enabled(struct Scene *scene, struct ModifierData *md, DerivedMesh *dm);
 void makeDerivedMesh(struct Scene *scene, struct Object *ob, struct BMEditMesh *em, 
-       CustomDataMask dataMask, int build_shapekey_layers);
+                     CustomDataMask dataMask, int build_shapekey_layers);
 
-/* returns an array of deform matrices for crazyspace correction, and the
+/** returns an array of deform matrices for crazyspace correction, and the
  * number of modifiers left */
 int editbmesh_get_first_deform_matrices(struct Scene *, struct Object *, struct BMEditMesh *em,
-                                                                          float (**deformmats)[3][3], float (**deformcos)[3]);
+                                        float (**deformmats)[3][3], float (**deformcos)[3]);
 
 void weight_to_rgb(float r_rgb[3], const float weight);
-/* Update the weight MCOL preview layer.
+/** 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.
@@ -651,39 +670,39 @@ void weight_to_rgb(float r_rgb[3], const float 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
+/** 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 */
 typedef struct DMVertexAttribs {
        struct {
                struct MTFace *array;
-               int emOffset, glIndex, glTexco;
+               int em_offset, gl_index, gl_texco;
        } tface[MAX_MTFACE];
 
        struct {
                struct MCol *array;
-               int emOffset, glIndex;
+               int em_offset, gl_index;
        } mcol[MAX_MCOL];
 
        struct {
                float (*array)[4];
-               int emOffset, glIndex;
+               int em_offset, gl_index;
        } tang;
 
        struct {
                float (*array)[3];
-               int emOffset, glIndex, glTexco;
+               int em_offset, gl_index, gl_texco;
        } orco;
 
        int tottface, totmcol, tottang, totorco;
 } DMVertexAttribs;
 
 void DM_vertex_attributes_from_gpu(DerivedMesh *dm,
-       struct GPUVertexAttribs *gattribs, DMVertexAttribs *attribs);
+                                   struct GPUVertexAttribs *gattribs, DMVertexAttribs *attribs);
 
 void DM_add_tangent_layer(DerivedMesh *dm);
 void DM_calc_auto_bump_scale(DerivedMesh *dm);
 
-/* Set object's bounding box based on DerivedMesh min/max data */
+/** Set object's bounding box based on DerivedMesh min/max data */
 void DM_set_object_boundbox(struct Object *ob, DerivedMesh *dm);
 
 void DM_init_origspace(DerivedMesh *dm);
@@ -692,6 +711,19 @@ void DM_init_origspace(DerivedMesh *dm);
 #ifndef NDEBUG
 char *DM_debug_info(DerivedMesh *dm);
 void DM_debug_print(DerivedMesh *dm);
+void DM_debug_print_cdlayers(CustomData *cdata);
+#endif
+
+#ifdef __GNUC__
+BLI_INLINE int DM_origindex_mface_mpoly(const int *index_mf_to_mpoly, const int *index_mp_to_orig, const int i)
+       __attribute__((nonnull(1)))
+;
 #endif
 
+BLI_INLINE int DM_origindex_mface_mpoly(const int *index_mf_to_mpoly, const int *index_mp_to_orig, const int i)
+{
+       const int j = index_mf_to_mpoly[i];
+       return (j != ORIGINDEX_NONE) ? (index_mp_to_orig ? index_mp_to_orig[j] : j) : ORIGINDEX_NONE;
+}
+
 #endif