ok, apparently didn't commit this either. apparently includes a merge with trunk...
[blender-staging.git] / source / blender / blenkernel / BKE_DerivedMesh.h
index 514411e137dfe19d180e4948a915e3691c732f2f..c1fe8f0452e308b6ecbd70579daef5765aa0be37 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.
+  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 
+  one format to another.
+
+  All Mesh structures in blender make use of CustomData, which is used to store
+  per-element attributes and interpolate them (e.g. uvs, vcols, vgroups, etc).
+  
+  Mesh is the "serialized" structure, used for storing object-mode mesh data
+  and also for saving stuff to disk.  It's interfaces are also what DerivedMesh
+  uses to communicate with.
+  
+  CDDM is a little mesh library, that uses Mesh data structures in the backend.
+  It's mostly used for modifiers, and has the advantages of not taking much
+  resources.
+
+  BMesh is a full-on brep, used for editmode, some modifiers, etc.  It's much
+  more capable (if memory-intensive) then CDDM.
+
+  DerivedMesh is somewhat hackish.  Many places assumes that a DerivedMesh is
+  a CDDM (most of the time by simply copying it and converting it to one).
+  CDDM is the original structure for modifiers, but has since been superseded
+  by BMesh, at least for the foreseeable future.
+*/
+
+/* 
+ * Note: This sturcture is read-only, for all practical purposes.
+ *       At some point in the future, we may want to consider
+ *       creating a replacement structure that implements a proper
+ *       abstract mesh kernel interface.  Or, we can leave this
+ *       as it is and stick with using BMesh and CDDM.
+ */
+
 /* TODO (Probably)
  *
  *  o Make drawMapped* functions take a predicate function that
@@ -43,6 +82,8 @@
  */
 
 #include "DNA_customdata_types.h"
+#include "DNA_meshdata_types.h"
+
 #include "BKE_customdata.h"
 #include "BKE_bvhutils.h"
 
@@ -53,46 +94,104 @@ struct MTFace;
 struct Object;
 struct Scene;
 struct Mesh;
-struct EditMesh;
+struct BMEditMesh;
 struct KeyBlock;
 struct ModifierData;
 struct MCol;
 struct ColorBand;
 struct GPUVertexAttribs;
 struct GPUDrawObject;
+struct BMEditMesh;
 
 /* number of sub-elements each mesh element has (for interpolation) */
 #define SUB_ELEMS_VERT 0
 #define SUB_ELEMS_EDGE 2
-#define SUB_ELEMS_FACE 4
+#define SUB_ELEMS_FACE 50
+
+/*
+Note: all mface interfaces now officially operate on tesselated data.
+      Also, the mface origindex layer indexes mpolys, not mfaces.
+*/
+
+/*DM Iterators.  For now, first implement face iterators.
+  These are read-only, at least for now.*/
+
+typedef struct DMLoopIter {
+       void (*step)(void *self);
+       int done;
+
+       int index, vindex, eindex;
+       MVert v; /*copy of the associated vert's data*/ 
+
+       /*note: if layer is -1, then the active layer is retrieved.
+         loop refers to per-face-vertex data.*/
+       void *(*getLoopCDData)(void *self, int type, int layer);
+       void *(*getVertCDData)(void *self, int type, int layer);
+       
+/* derivedmesh 2.0 interface ideas (will likely never be implemented ;):
+        void (*interpLoopData)(void *self, void **src_blocks, 
+                              float *weights, float *sub_weights, int count);
+
+        //a generic handle for a loop
+       intptr_t lhandle;
+
+       inside DerivedMesh itself:
+       //
+       //void (*interpLoopData)(DerivedMesh *dm, DMLoopIter *destloop, 
+       //                       intptr_t *loop_handles, int totloop);
+*/
+} DMLoopIter;
+
+typedef struct DMFaceIter {
+       void (*step)(void *self);
+       void (*free)(void *self);
+       int done;
+
+       int index;
+       int len;
+       int mat_nr;
+       int flags;
+
+       /*note: you may only use one
+         loop iterator at a time.*/
+       DMLoopIter *(*getLoopsIter)(void *self);
+
+       /*if layer is -1, returns active layer*/
+       void *(*getCDData)(void *self, int type, int layer);
+} DMFaceIter;
 
 typedef struct DerivedMesh DerivedMesh;
 struct DerivedMesh {
        /* Private DerivedMesh data, only for internal DerivedMesh use */
-       CustomData vertData, edgeData, faceData;
-       int numVertData, numEdgeData, numFaceData;
+       CustomData vertData, edgeData, faceData, loopData, polyData;
+       int numVertData, numEdgeData, numFaceData, numLoopData, numPolyData;
        int needsFree; /* checked on ->release, is set to 0 for cached results */
        int deformedOnly; /* set by modifier stack if only deformed from original */
        BVHCache bvhCache;
        struct GPUDrawObject *drawObject;
 
        /* Misc. Queries */
+       
+       /*face iterator.  initializes iter.*/
+       DMFaceIter *(*newFaceIter)(DerivedMesh *dm);
+
+       /*recalculates mesh tesselation*/
+       void (*recalcTesselation)(DerivedMesh *dm);
 
        /* Also called in Editmode */
        int (*getNumVerts)(DerivedMesh *dm);
-       /* Also called in Editmode */
-       int (*getNumFaces)(DerivedMesh *dm);
-
        int (*getNumEdges)(DerivedMesh *dm);
+       int (*getNumTessFaces)(DerivedMesh *dm);
+       int (*getNumFaces) (DerivedMesh *dm);
 
-       /* copy a single vert/edge/face from the derived mesh into
+       /* copy a single vert/edge/tesselated 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)
         */
        void (*getVert)(DerivedMesh *dm, int index, struct MVert *vert_r);
        void (*getEdge)(DerivedMesh *dm, int index, struct MEdge *edge_r);
-       void (*getFace)(DerivedMesh *dm, int index, struct MFace *face_r);
+       void (*getTessFace)(DerivedMesh *dm, int index, struct MFace *face_r);
 
        /* 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,
@@ -101,21 +200,21 @@ struct DerivedMesh {
         */
        struct MVert *(*getVertArray)(DerivedMesh *dm);
        struct MEdge *(*getEdgeArray)(DerivedMesh *dm);
-       struct MFace *(*getFaceArray)(DerivedMesh *dm);
+       struct MFace *(*getTessFaceArray)(DerivedMesh *dm);
 
        /* 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);
        void (*copyEdgeArray)(DerivedMesh *dm, struct MEdge *edge_r);
-       void (*copyFaceArray)(DerivedMesh *dm, struct MFace *face_r);
+       void (*copyTessFaceArray)(DerivedMesh *dm, struct MFace *face_r);
 
        /* 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 *(*dupFaceArray)(DerivedMesh *dm);
+       struct MFace *(*dupTessFaceArray)(DerivedMesh *dm);
 
        /* 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
@@ -123,7 +222,7 @@ struct DerivedMesh {
         */
        void *(*getVertData)(DerivedMesh *dm, int index, int type);
        void *(*getEdgeData)(DerivedMesh *dm, int index, int type);
-       void *(*getFaceData)(DerivedMesh *dm, int index, int type);
+       void *(*getTessFaceData)(DerivedMesh *dm, int index, int type);
 
        /* 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
@@ -131,8 +230,21 @@ struct DerivedMesh {
         */
        void *(*getVertDataArray)(DerivedMesh *dm, int type);
        void *(*getEdgeDataArray)(DerivedMesh *dm, int type);
-       void *(*getFaceDataArray)(DerivedMesh *dm, int type);
-
+       void *(*getTessFaceDataArray)(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 *(*getFaceDataLayout)(DerivedMesh *dm);
+       
+       /*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);
+       
        /* 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
@@ -221,7 +333,7 @@ struct DerivedMesh {
         */
        void (*drawFacesTex)(DerivedMesh *dm,
                             int (*setDrawOptions)(struct MTFace *tface,
-                            struct MCol *mcol, int matnr));
+                            int has_vcol, int matnr));
 
        /* Draw all faces with GLSL materials
         *  o setMaterial is called for every different material nr
@@ -302,13 +414,15 @@ void DM_init_funcs(DerivedMesh *dm);
  * of vertices, edges and faces (doesn't allocate memory for them, just
  * sets up the custom data layers)
  */
-void DM_init(DerivedMesh *dm, int numVerts, int numEdges, int numFaces);
+void DM_init(DerivedMesh *dm, int numVerts, int numEdges, int numFaces,
+            int numLoops, int numPolys);
 
 /* utility function to initialise 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,
-                      int numVerts, int numEdges, int numFaces);
+                      int numVerts, int numEdges, int numFaces,
+                     int numLoops, int numPolys);
 
 /* utility function to release a DerivedMesh's layers
  * returns 1 if DerivedMesh has to be released by the backend, 0 otherwise
@@ -338,6 +452,8 @@ void DM_add_vert_layer(struct DerivedMesh *dm, int type, int alloctype,
                        void *layer);
 void DM_add_edge_layer(struct DerivedMesh *dm, int type, int alloctype,
                        void *layer);
+void DM_add_tessface_layer(struct DerivedMesh *dm, int type, int alloctype,
+                       void *layer);
 void DM_add_face_layer(struct DerivedMesh *dm, int type, int alloctype,
                        void *layer);
 
@@ -357,6 +473,7 @@ void *DM_get_face_data(struct DerivedMesh *dm, int index, int type);
  */
 void *DM_get_vert_data_layer(struct DerivedMesh *dm, int type);
 void *DM_get_edge_data_layer(struct DerivedMesh *dm, int type);
+void *DM_get_tessface_data_layer(struct DerivedMesh *dm, int type);
 void *DM_get_face_data_layer(struct DerivedMesh *dm, int type);
 
 /* custom data setting functions
@@ -375,6 +492,10 @@ void DM_copy_vert_data(struct DerivedMesh *source, struct DerivedMesh *dest,
                        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_loop_data(struct DerivedMesh *source, struct DerivedMesh *dest,
+                       int source_index, int dest_index, int count);
 void DM_copy_face_data(struct DerivedMesh *source, struct DerivedMesh *dest,
                        int source_index, int dest_index, int count);
 
@@ -384,8 +505,13 @@ void DM_copy_face_data(struct DerivedMesh *source, struct DerivedMesh *dest,
  */
 void DM_free_vert_data(struct DerivedMesh *dm, int index, int count);
 void DM_free_edge_data(struct DerivedMesh *dm, int index, int count);
+void DM_free_tessface_data(struct DerivedMesh *dm, int index, int count);
+void DM_free_loop_data(struct DerivedMesh *dm, int index, int count);
 void DM_free_face_data(struct DerivedMesh *dm, int index, int count);
 
+/*sets up mpolys for a DM based on face iterators in source*/
+void DM_DupPolys(DerivedMesh *source, DerivedMesh *target);
+
 /* 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
@@ -415,12 +541,20 @@ void DM_interp_edge_data(struct DerivedMesh *source, struct DerivedMesh *dest,
  * vert_weights[i] multiplied by weights[i].
  */
 typedef float FaceVertWeight[SUB_ELEMS_FACE][SUB_ELEMS_FACE];
-void DM_interp_face_data(struct DerivedMesh *source, struct DerivedMesh *dest,
+void DM_interp_tessface_data(struct DerivedMesh *source, struct DerivedMesh *dest,
                          int *src_indices,
                          float *weights, FaceVertWeight *vert_weights,
                          int count, int dest_index);
 
-void DM_swap_face_data(struct DerivedMesh *dm, int index, int *corner_indices);
+void DM_swap_tessface_data(struct DerivedMesh *dm, int index, int *corner_indices);
+
+void DM_interp_loop_data(struct DerivedMesh *source, struct DerivedMesh *dest,
+                         int *src_indices,
+                         float *weights, int count, int dest_index);
+
+void DM_interp_face_data(struct DerivedMesh *source, struct DerivedMesh *dest,
+                         int *src_indices,
+                         float *weights, int count, int dest_index);
 
 /* Temporary? A function to give a colorband to derivedmesh for vertexcolor ranges */
 void vDM_ColorBand_store(struct ColorBand *coba);
@@ -441,6 +575,9 @@ DerivedMesh *mesh_create_derived_for_modifier(struct Scene *scene, struct Object
 DerivedMesh *mesh_create_derived_render(struct Scene *scene, struct Object *ob,
                                         CustomDataMask dataMask);
 
+DerivedMesh *getEditDerivedBMesh(struct BMEditMesh *em, struct Object *ob,
+                                           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 */
@@ -456,17 +593,17 @@ DerivedMesh *mesh_create_derived_no_deform_render(struct Scene *scene, struct Ob
 DerivedMesh *mesh_create_derived_no_virtual(struct Scene *scene, struct Object *ob, float (*vertCos)[3],
                                             CustomDataMask dataMask);
 
-DerivedMesh *editmesh_get_derived_base(struct Object *, struct EditMesh *em);
-DerivedMesh *editmesh_get_derived_cage(struct Scene *scene, struct Object *, 
-                                                                          struct EditMesh *em, CustomDataMask dataMask);
-DerivedMesh *editmesh_get_derived_cage_and_final(struct Scene *scene, struct Object *, 
-                                                                                                struct EditMesh *em, DerivedMesh **final_r,
+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);
+DerivedMesh *editbmesh_get_derived_cage_and_final(struct Scene *scene, struct Object *, 
+                                                struct BMEditMesh *em, DerivedMesh **final_r,
                                                  CustomDataMask dataMask);
-void makeDerivedMesh(struct Scene *scene, struct Object *ob, struct EditMesh *em, CustomDataMask dataMask);
+void makeDerivedMesh(struct Scene *scene, struct Object *ob, struct BMEditMesh *em, CustomDataMask dataMask);
 
 /* returns an array of deform matrices for crazyspace correction, and the
    number of modifiers left */
-int editmesh_get_first_deform_matrices(struct Object *, struct EditMesh *em, float (**deformmats)[3][3],
+int editbmesh_get_first_deform_matrices(struct Object *, struct BMEditMesh *em, float (**deformmats)[3][3],
                                        float (**deformcos)[3]);
 
 void weight_to_rgb(float input, float *fr, float *fg, float *fb);