Added custom vertex/edge/face data for meshes:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Mon, 20 Nov 2006 04:28:02 +0000 (04:28 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Mon, 20 Nov 2006 04:28:02 +0000 (04:28 +0000)
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.

Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData

Replaced TFace by MTFace:

This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.

Removed DispListMesh:

This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.

Removed ssDM and meshDM DerivedMesh backends:

The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.

This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.

89 files changed:
source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/BKE_bad_level_calls.h
source/blender/blenkernel/BKE_cdderivedmesh.h
source/blender/blenkernel/BKE_customdata.h
source/blender/blenkernel/BKE_displist.h
source/blender/blenkernel/BKE_mesh.h
source/blender/blenkernel/BKE_subsurf.h
source/blender/blenkernel/bad_level_call_stubs/stubs.c
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/anim.c
source/blender/blenkernel/intern/armature.c
source/blender/blenkernel/intern/cdderivedmesh.c
source/blender/blenkernel/intern/customdata.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/exotic.c
source/blender/blenkernel/intern/lattice.c
source/blender/blenkernel/intern/mesh.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/softbody.c
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/include/BDR_drawmesh.h
source/blender/include/BDR_editface.h
source/blender/include/BDR_vpaint.h
source/blender/include/BIF_editmesh.h
source/blender/include/BSE_types.h
source/blender/makesdna/DNA_customdata_types.h
source/blender/makesdna/DNA_mesh_types.h
source/blender/makesdna/DNA_meshdata_types.h
source/blender/makesdna/intern/makesdna.c
source/blender/python/api2_2x/Mesh.c
source/blender/python/api2_2x/NMesh.c
source/blender/radiosity/extern/include/radio_types.h
source/blender/radiosity/intern/source/radio.c
source/blender/radiosity/intern/source/radpostprocess.c
source/blender/radiosity/intern/source/radpreprocess.c
source/blender/render/intern/include/render_types.h
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/rendercore.c
source/blender/src/booleanops.c
source/blender/src/buttons_editing.c
source/blender/src/drawimage.c
source/blender/src/drawmesh.c
source/blender/src/drawobject.c
source/blender/src/drawview.c
source/blender/src/editdeform.c
source/blender/src/editface.c
source/blender/src/editmesh.c
source/blender/src/editmesh_lib.c
source/blender/src/editmesh_mods.c
source/blender/src/editmesh_tools.c
source/blender/src/editobject.c
source/blender/src/editsima.c
source/blender/src/editview.c
source/blender/src/filesel.c
source/blender/src/fluidsim.c
source/blender/src/header_view3d.c
source/blender/src/imagepaint.c
source/blender/src/meshtools.c
source/blender/src/multires.c
source/blender/src/poseobject.c
source/blender/src/sculptmode.c
source/blender/src/space.c
source/blender/src/transform_conversions.c
source/blender/src/unwrapper.c
source/blender/src/verse_mesh.c
source/blender/src/verse_object.c
source/blender/src/vpaint.c
source/blender/yafray/intern/export_File.cpp
source/blender/yafray/intern/export_Plugin.cpp
source/blender/yafray/intern/export_Plugin.h
source/blender/yafray/intern/yafray_Render.cpp
source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
source/gameengine/BlenderRoutines/KX_BlenderGL.h
source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.cpp
source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.h
source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp
source/gameengine/GamePlayer/common/GPC_PolygonMaterial.h
source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
source/gameengine/GamePlayer/common/GPC_RenderTools.h
source/gameengine/Ketsji/BL_Material.h
source/gameengine/Ketsji/KX_BlenderMaterial.cpp
source/gameengine/Ketsji/KX_BlenderMaterial.h
source/gameengine/Ketsji/KX_PolygonMaterial.cpp
source/gameengine/Ketsji/KX_PolygonMaterial.h

index 4506f5740fb714ffe9a7accd22709aed3da5fe6f..8a72b9ae2a90ad8d5b4f3e31609f67eb79a352c8 100644 (file)
 struct MVert;
 struct MEdge;
 struct MFace;
-struct TFace;
+struct MTFace;
 struct Object;
 struct Mesh;
 struct EditMesh;
-struct DispListMesh;
 struct ModifierData;
+struct MCol;
 
 /* number of sub-elements each mesh element has (for interpolation) */
 #define SUB_ELEMS_VERT 0
@@ -64,8 +64,10 @@ struct ModifierData;
 
 typedef struct DerivedMesh DerivedMesh;
 struct DerivedMesh {
-       /* custom data for verts, edges & faces */
+       /* Private DerivedMesh data, only for internal DerivedMesh use */
        CustomData vertData, edgeData, faceData;
+       int numVertData, numEdgeData, numFaceData;
+       int needsFree; /* checked on ->release, is set to 0 for cached results */
 
        /* Misc. Queries */
 
@@ -77,18 +79,29 @@ struct DerivedMesh {
        int (*getNumEdges)(DerivedMesh *dm);
 
        /* copy a single vert/edge/face from the derived mesh into
-        * *{vert/edge/face}_r
+        * *{vert/edge/face}_r. note that the current implementation
+        * of this function can be quite slow, iterating over all
+        * elements (editmesh, verse mesh)
         */
        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);
 
+       /* 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 *(*getFaceArray)(DerivedMesh *dm);
+
        /* copy all verts/edges/faces from the derived mesh into
         * *{vert/edge/face}_r (must point to a buffer large enough)
         */
-       void (*getVertArray)(DerivedMesh *dm, struct MVert *vert_r);
-       void (*getEdgeArray)(DerivedMesh *dm, struct MEdge *edge_r);
-       void (*getFaceArray)(DerivedMesh *dm, struct MFace *face_r);
+       void (*copyVertArray)(DerivedMesh *dm, struct MVert *vert_r);
+       void (*copyEdgeArray)(DerivedMesh *dm, struct MEdge *edge_r);
+       void (*copyFaceArray)(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
@@ -142,16 +155,6 @@ struct DerivedMesh {
                                                     float *cent, float *no),
                                        void *userData);
 
-       /* Convert to new DispListMesh, should be free'd by caller.
-        *
-        * If allowShared is true then the caller is committing to not free'ng
-        * the DerivedMesh before free'ng the DispListMesh, which means that
-        * certain fields of the returned DispListMesh can safely be share with
-        * the DerivedMesh's internal data.
-        */
-       struct DispListMesh* (*convertToDispListMesh)(DerivedMesh *dm,
-                                                     int allowShared);
-
        /* Iterate over all vertex points, calling DO_MINMAX with given args.
         *
         * Also called in Editmode
@@ -205,11 +208,12 @@ struct DerivedMesh {
        void (*drawFacesColored)(DerivedMesh *dm, int useTwoSided,
                                 unsigned char *col1, unsigned char *col2);
 
-       /* Draw all faces using TFace 
+       /* Draw all faces using MTFace 
         *  o Drawing options too complicated to enumerate, look at code.
         */
        void (*drawFacesTex)(DerivedMesh *dm,
-                            int (*setDrawOptions)(struct TFace *tface, int matnr));
+                            int (*setDrawOptions)(struct MTFace *tface,
+                            struct MCol *mcol, int matnr));
 
        /* Draw mapped faces (no color, or texture)
         *  o Only if !setDrawOptions or
@@ -229,7 +233,7 @@ struct DerivedMesh {
                                                      int *drawSmooth_r),
                                void *userData, int useColors);
 
-       /* Draw mapped faces using TFace 
+       /* Draw mapped faces using MTFace 
         *  o Drawing options too complicated to enumerate, look at code.
         */
        void (*drawMappedFacesTex)(DerivedMesh *dm,
@@ -260,6 +264,8 @@ struct DerivedMesh {
                                                                   float t),
                                      void *userData);
 
+       /* Release reference to the DerivedMesh. This function decides internally
+        * if the DerivedMesh will be freed, or cached for later use. */
        void (*release)(DerivedMesh *dm);
 };
 
@@ -281,8 +287,9 @@ void DM_from_template(DerivedMesh *dm, DerivedMesh *source,
                       int numVerts, int numEdges, int numFaces);
 
 /* utility function to release a DerivedMesh's layers
+ * returns 1 if DerivedMesh has to be released by the backend, 0 otherwise
  */
-void DM_release(DerivedMesh *dm);
+int DM_release(DerivedMesh *dm);
 
 /* utility function to convert a DerivedMesh to a Mesh
  */
@@ -381,16 +388,16 @@ void DM_interp_face_data(struct DerivedMesh *source, struct DerivedMesh *dest,
                          float *weights, FaceVertWeight *vert_weights,
                          int count, int dest_index);
 
-    /* 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/weigt paint and particles */
-float *mesh_get_mapped_verts_nors(struct Object *ob);
+void DM_swap_face_data(struct DerivedMesh *dm, int index, int *corner_indices);
 
-       /* Internal function, just temporarily exposed */
-DerivedMesh *derivedmesh_from_displistmesh(struct DispListMesh *dlm, float (*vertexCos)[3]);
+/* 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/weigt paint and particles */
+float *mesh_get_mapped_verts_nors(struct Object *ob);
 
-DerivedMesh *mesh_get_derived_final(struct Object *ob, int *needsFree_r);
-DerivedMesh *mesh_get_derived_deform(struct Object *ob, int *needsFree_r);
+       /* */
+DerivedMesh *mesh_get_derived_final(struct Object *ob);
+DerivedMesh *mesh_get_derived_deform(struct Object *ob);
 
 DerivedMesh *mesh_create_derived_for_modifier(struct Object *ob, struct ModifierData *md);
 
@@ -400,8 +407,8 @@ DerivedMesh *mesh_create_derived_no_deform(struct Object *ob, float (*vertCos)[3
 DerivedMesh *mesh_create_derived_no_deform_render(struct Object *ob, float (*vertCos)[3]);
 
 DerivedMesh *editmesh_get_derived_base(void);
-DerivedMesh *editmesh_get_derived_cage(int *needsFree_r);
-DerivedMesh *editmesh_get_derived_cage_and_final(DerivedMesh **final_r, int *cageNeedsFree_r, int *finalNeedsFree_r);
+DerivedMesh *editmesh_get_derived_cage(void);
+DerivedMesh *editmesh_get_derived_cage_and_final(DerivedMesh **final_r);
 
 void weight_to_rgb(float input, float *fr, float *fg, float *fb);
 
index 91268ffe2439fa1406b242639d444b09b1cb048e..7eeb0c4b1d97c0d5cfd9d4fd6b4847a5292c3304 100644 (file)
@@ -145,11 +145,9 @@ void bglVertex3fv(float *vec);
 void bglVertex3f(float x, float y, float z);
 void bglEnd(void);
 
-struct DispListMesh;
 struct Object;
 
 /* booleanops.c */
-struct DispListMesh *NewBooleanMeshDLM(struct Object *ob, struct Object *ob_select, int int_op_type);
 struct DerivedMesh *NewBooleanDerivedMesh(struct Object *ob,
                                 struct Object *ob_select, int int_op_type);
 
index b83134405514bde4df01f04e9e92cdc821f76378..a570b4fe598f363dd5a57488136727b935addaaa 100644 (file)
 struct DerivedMesh;
 struct EditMesh;
 struct Mesh;
+struct Object;
 
 /* creates a new CDDerivedMesh */
 struct DerivedMesh *CDDM_new(int numVerts, int numEdges, int numFaces);
 
-/* creates a CDDerivedMesh from the given Mesh */
-struct DerivedMesh *CDDM_from_mesh(struct Mesh *mesh);
+/* creates a CDDerivedMesh from the given Mesh, this will reference the
+   original data in Mesh, but it is safe to apply vertex coordinates or
+   calculate normals as those functions will automtically create new
+   data to not overwrite the original */
+struct DerivedMesh *CDDM_from_mesh(struct Mesh *mesh, struct Object *ob);
 
 /* creates a CDDerivedMesh from the given EditMesh */
 struct DerivedMesh *CDDM_from_editmesh(struct EditMesh *em, struct Mesh *me);
@@ -62,11 +66,14 @@ struct DerivedMesh *CDDM_copy(struct DerivedMesh *dm);
 struct DerivedMesh *CDDM_from_template(struct DerivedMesh *source,
                                   int numVerts, int numEdges, int numFaces);
 
-/* applies vertex coordinates to a CDDerivedMesh
+/* applies vertex coordinates or normals to a CDDerivedMesh. if the MVert
+ * layer is a referenced layer, it will be duplicate to not overwrite the
+ * original
  */
 void CDDM_apply_vert_coords(struct DerivedMesh *cddm, float (*vertCoords)[3]);
+void CDDM_apply_vert_normals(struct DerivedMesh *cddm, short (*vertNormals)[3]);
 
-/* recalculates normals for a CDDerivedMesh
+/* recalculates vertex and face normals for a CDDerivedMesh
  */
 void CDDM_calc_normals(struct DerivedMesh *dm);
 
@@ -75,12 +82,12 @@ void CDDM_calc_normals(struct DerivedMesh *dm);
  */
 void CDDM_calc_edges(struct DerivedMesh *dm);
 
-/* sets the number of vertices/edges/faces in a CDDerivedMesh
- * if the value given is more than the maximum, the maximum is used
+/* lowers the number of vertices/edges/faces in a CDDerivedMesh
+ * the layer data stays the same size
  */
-void CDDM_set_num_verts(struct DerivedMesh *dm, int numVerts);
-void CDDM_set_num_edges(struct DerivedMesh *dm, int numEdges);
-void CDDM_set_num_faces(struct DerivedMesh *dm, int numFaces);
+void CDDM_lower_num_verts(struct DerivedMesh *dm, int numVerts);
+void CDDM_lower_num_edges(struct DerivedMesh *dm, int numEdges);
+void CDDM_lower_num_faces(struct DerivedMesh *dm, int numFaces);
 
 /* vertex/edge/face access functions
  * should always succeed if index is within bounds
index b36ab67f5e1e3ec3d24921e5a05eca0b2aa6ba49..ce32f06e320e946a3bb90dafcb1d1614f3c4e7b4 100644 (file)
 #define BKE_CUSTOMDATA_H
 
 struct CustomData;
+struct CustomDataLayer;
+typedef int CustomDataMask;
 
-#define ORIGINDEX_NONE -1 /* indicates no original index for this element */
+extern CustomDataMask CD_MASK_MESH[];
+extern CustomDataMask CD_MASK_EDITMESH[];
+extern CustomDataMask CD_MASK_DERIVEDMESH[];
 
-/* layer flags - to be used with CustomData_add_layer */
+/* for ORIGINDEX layer type, indicates no original index for this element */
+#define ORIGINDEX_NONE -1
 
-/* indicates layer should not be copied by CustomData_from_template or
- * CustomData_copy_data (for temporary utility layers)
- */
-#define LAYERFLAG_NOCOPY 1<<0
+/* initialises a CustomData object with the same layer setup as source and
+ * memory space for totelem elements. mask must be an array of length
+ * CD_NUMTYPES elements, that indicate if a layer can be copied. */
 
-/* indicates layer should not be freed (for layers backed by external data)
- */
-#define LAYERFLAG_NOFREE 1<<1
+/* copy/merge allocation types */
+#define CD_CALLOC    0  /* allocate blank memory for all layers */
+#define CD_DEFAULT   1  /* allocate layers and set them to their defaults */
+#define CD_DUPLICATE 2  /* do a full copy of all layer */
+#define CD_REFERENCE 3  /* reference original pointers, set layer flag NOFREE */
 
-/* initialises a CustomData object with space for the given number
- * of data layers and the given number of elements per layer
- */
-void CustomData_init(struct CustomData *data,
-                     int maxLayers, int maxElems, int subElems);
+/* initialises a CustomData object with the same layer setup as source.
+ * mask must be an array of length CD_NUMTYPES elements, that indicates
+ * if a layer should be copied or not. alloctype must be one of the above. */
+void CustomData_copy(const struct CustomData *source, struct CustomData *dest,
+                     CustomDataMask *mask, int alloctype, int totelem);
 
-/* initialises a CustomData object with the same layer setup as source
- * and memory space for maxElems elements. flag is added to all layer flags
- */
-void CustomData_from_template(const struct CustomData *source,
-                              struct CustomData *dest, int flag, int maxElems);
+/* same as the above, except that will preserve existing layers, and only add
+ * the layers that were not there yet */
+void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
+                      CustomDataMask *mask, int alloctype, int totelem);
 
 /* frees data associated with a CustomData object (doesn't free the object
  * itself, though)
  */
-void CustomData_free(struct CustomData *data);
+void CustomData_free(struct CustomData *data, int totelem);
+
+/* frees all layers with flag LAYERFLAG_TEMPORARY */
+void CustomData_free_temporary(struct CustomData *data, int totelem);
 
 /* adds a data layer of the given type to the CustomData object, optionally
  * backed by an external data array
@@ -70,20 +78,19 @@ void CustomData_free(struct CustomData *data);
  * is allocated
  * the layer data will be freed by CustomData_free unless
  * (flag & LAYERFLAG_NOFREE) is true
- * grows the number of layers in data if data->maxLayers has been reached
- * returns 1 on success, 0 on failure
+ * returns the data of the layer
  *
  * in editmode, use EM_add_data_layer instead of this function
  */
-int CustomData_add_layer(struct CustomData *data, int type, int flag,
-                         void *layer);
+void *CustomData_add_layer(struct CustomData *data, int type, int flag,
+                           void *layer, int totelem);
 
 /* frees the first data layer with the give type.
  * returns 1 on succes, 0 if no layer with the given type is found
  *
  * in editmode, use EM_free_data_layer instead of this function
  */
-int CustomData_free_layer(struct CustomData *data, int type);
+int CustomData_free_layer(struct CustomData *data, int type, int totelem);
 
 /* returns 1 if the two objects are compatible (same layer types and
  * flags in the same order), 0 if not
@@ -94,22 +101,26 @@ int CustomData_compat(const struct CustomData *data1,
 /* returns 1 if a layer with the specified type exists */
 int CustomData_has_layer(const struct CustomData *data, int type);
 
+/* duplicate data of a layer with flag NOFREE, and remove that flag.
+ * returns the layer data */
+void *CustomData_duplicate_referenced_layer(struct CustomData *data, int type);
+
 /* copies data from one CustomData object to another
  * objects need not be compatible, each source layer is copied to the
  * first dest layer of correct type (if there is none, the layer is skipped)
  * return 1 on success, 0 on failure
  */
-int CustomData_copy_data(const struct CustomData *source,
-                         struct CustomData *dest, int source_index,
-                         int dest_index, int count);
-int CustomData_em_copy_data(const struct CustomData *source,
+void CustomData_copy_data(const struct CustomData *source,
+                          struct CustomData *dest, int source_index,
+                          int dest_index, int count);
+void CustomData_em_copy_data(const struct CustomData *source,
                             struct CustomData *dest, void *src_block,
                             void **dest_block);
 
 /* frees data in a CustomData object
  * return 1 on success, 0 on failure
  */
-int CustomData_free_elem(struct CustomData *data, int index, int count);
+void CustomData_free_elem(struct CustomData *data, int index, int count);
 
 /* interpolates data from one CustomData object to another
  * objects need not be compatible, each source layer is interpolated to the
@@ -125,12 +136,17 @@ int CustomData_free_elem(struct CustomData *data, int index, int count);
  *
  * returns 1 on success, 0 on failure
  */
-int CustomData_interp(const struct CustomData *source, struct CustomData *dest,
-                      int *src_indices, float *weights, float *sub_weights,
-                      int count, int dest_index);
-int CustomData_em_interp(struct CustomData *data,  void **src_blocks,
-                         float *weights, float *sub_weights, int count,
-                         void *dest_block);
+void CustomData_interp(const struct CustomData *source, struct CustomData *dest,
+                       int *src_indices, float *weights, float *sub_weights,
+                       int count, int dest_index);
+void CustomData_em_interp(struct CustomData *data,  void **src_blocks,
+                          float *weights, float *sub_weights, int count,
+                          void *dest_block);
+
+/* swaps the data in the element corners, to new corners with indices as
+   specified in corner_indices. for edges this is an array of length 2, for
+   faces an array of length 4 */
+void CustomData_swap(struct CustomData *data, int index, int *corner_indices);
 
 /* gets a pointer to the data element at index from the first layer of type
  * returns NULL if there is no layer of type
@@ -143,6 +159,11 @@ void *CustomData_em_get(const struct CustomData *data, void *block, int type);
  */
 void *CustomData_get_layer(const struct CustomData *data, int type);
 
+/* set the pointer of to the first layer of type. the old data is not freed.
+ * returns the value of ptr if the layer is found, NULL otherwise
+ */
+void *CustomData_set_layer(const struct CustomData *data, int type, void *ptr);
+
 /* copies the data from source to the data element at index in the first
  * layer of type
  * no effect if there is no layer of type
@@ -152,10 +173,8 @@ void CustomData_set(const struct CustomData *data, int index, int type,
 void CustomData_em_set(struct CustomData *data, void *block, int type,
                        void *source);
 
-/* sets the number of elements in a CustomData object
- * if the value given is more than the maximum, the maximum is used
- */
-void CustomData_set_num_elems(struct CustomData *data, int numElems);
+/* set data layers that have a non-zero default value to their defaults */
+void CustomData_set_default(struct CustomData *data, int index, int count);
 
 /* alloc/free a block of custom data attached to one element in editmode */
 void CustomData_em_set_default(struct CustomData *data, void **block);
@@ -168,4 +187,8 @@ void CustomData_to_em_block(const struct CustomData *source,
 void CustomData_from_em_block(const struct CustomData *source,
                               struct CustomData *dest, void *block, int index);
 
+/* query info over types */
+void CustomData_file_write_info(int type, char **structname, int *structnum);
+int CustomData_sizeof(int type);
+
 #endif
index 0bb74ca94b53fe5bbce67f774cf953947b974fcf..4bcd5d8955c6ab1c3ce5e598a021beb62dac44cb 100644 (file)
@@ -35,6 +35,8 @@
 #ifndef BKE_DISPLIST_H
 #define BKE_DISPLIST_H
 
+#include "DNA_customdata_types.h"
+
 /* dl->type */
 #define DL_POLY                 0
 #define DL_SEGM                 1
@@ -82,30 +84,6 @@ struct ListBase;
 struct Material;
 struct Bone;
 struct Mesh;
-struct TFace;
-struct EditMesh;
-struct EditEdge;
-struct EditFace;
-
-typedef struct DispListMesh DispListMesh;
-struct DispListMesh {
-       int totvert, totedge, totface;
-       struct MVert *mvert;
-       struct MEdge *medge;
-       struct MCol *mcol;
-       struct MFace *mface;
-       struct TFace *tface;
-       float *nors; // facenormals
-
-       int dontFreeVerts, dontFreeNors, dontFreeOther;
-};
-
-void displistmesh_free(DispListMesh *dlm);
-
-void displistmesh_to_mesh(DispListMesh *dlm, struct Mesh *me);
-
-DispListMesh *displistmesh_copy(DispListMesh *odlm);
-DispListMesh *displistmesh_copyShared(DispListMesh *odlm);
 
 /*
  * All the different DispList.type's use the
@@ -141,7 +119,7 @@ extern void addnormalsDispList(struct Object *ob, struct ListBase *lb);
 extern void count_displist(struct ListBase *lb, int *totvert, int *totface);
 extern void freedisplist(struct ListBase *lb);
 extern int displist_has_faces(struct ListBase *lb);
-extern void makeDispListMesh(struct Object *ob);
+extern void makeDerivedMesh(struct Object *ob);
 extern void makeDispListSurf(struct Object *ob, struct ListBase *dispbase, int forRender);
 extern void makeDispListCurveTypes(struct Object *ob, int forOrco);
 extern void makeDispListMBall(struct Object *ob);
@@ -154,8 +132,5 @@ void filldisplist(struct ListBase *dispbase, struct ListBase *to);
 
 void fastshade_free_render(void);
 
-
-void displistmesh_add_edges(DispListMesh *dlm);
-
 #endif
 
index e8d9dbe0681468fec531e73fb94d6b6eea1bb73b..f7cbe5810f6d1f8ec9a6053cd43844536735f0c9 100644 (file)
@@ -45,8 +45,9 @@ struct MFace;
 struct MVert;
 struct MCol;
 struct Object;
-struct TFace;
+struct MTFace;
 struct VecNor;
+struct CustomData;
 
 #ifdef __cplusplus
 extern "C" {
@@ -56,23 +57,21 @@ void unlink_mesh(struct Mesh *me);
 void free_mesh(struct Mesh *me);
 struct Mesh *add_mesh(void);
 struct Mesh *copy_mesh(struct Mesh *me);
+void mesh_update_customdata_pointers(struct Mesh *me);
 void make_local_tface(struct Mesh *me);
 void make_local_mesh(struct Mesh *me);
 void boundbox_mesh(struct Mesh *me, float *loc, float *size);
 void tex_space_mesh(struct Mesh *me);
 float *mesh_create_orco_render(struct Object *ob);
 float *mesh_create_orco(struct Object *ob);
-void test_index_face(struct MFace *mface, struct MCol *mc, struct TFace *tface, int nr);
+void test_index_face(struct MFace *mface, struct CustomData *mfdata, int mfindex, int nr);
 struct Mesh *get_mesh(struct Object *ob);
 void set_mesh(struct Object *ob, struct Mesh *me);
 void mball_to_mesh(struct ListBase *lb, struct Mesh *me);
 void nurbs_to_mesh(struct Object *ob);
-void mcol_to_tface(struct Mesh *me, int freedata);
-struct MCol *tface_to_mcol_p(struct TFace *tface, int totface);
-void tface_to_mcol(struct Mesh *me);
 void free_dverts(struct MDeformVert *dvert, int totvert);
 void copy_dverts(struct MDeformVert *dst, struct MDeformVert *src, int totvert); /* __NLA */
-int update_realtime_texture(struct TFace *tface, double time);
+int update_realtime_texture(struct MTFace *tface, double time);
 void mesh_delete_material_index(struct Mesh *me, int index);
 void mesh_set_smooth_flag(struct Object *meshOb, int enableSmooth);
 
@@ -103,7 +102,7 @@ typedef struct UvMapVert {
        unsigned char tfindex, separate;
 } UvMapVert;
 
-UvVertMap *make_uv_vert_map(struct MFace *mface, struct TFace *tface, unsigned int totface, unsigned int totvert, int selected, float *limit);
+UvVertMap *make_uv_vert_map(struct MFace *mface, struct MTFace *tface, unsigned int totface, unsigned int totvert, int selected, float *limit);
 UvMapVert *get_uv_map_vert(UvVertMap *vmap, unsigned int v);
 void free_uv_vert_map(UvVertMap *vmap);
 
index 3d1ffd3e52f636fc55782bee969465cf6ad315c6..459519913c52bd0fbfd6947aec73d412463d53fd 100644 (file)
@@ -37,9 +37,6 @@ struct DerivedMesh;
 struct EditMesh;
 struct SubsurfModifierData;
 
-struct DerivedMesh *subsurf_make_derived_from_editmesh(struct EditMesh *em, struct SubsurfModifierData *smd, float (*vertexCos)[3]);
-struct DerivedMesh *subsurf_make_derived_from_dlm_em(struct DispListMesh *dlm, struct SubsurfModifierData *smd, float (*vertCos)[3]);
-struct DerivedMesh *subsurf_make_derived_from_mesh(struct Mesh *me, struct DispListMesh *dlm, struct SubsurfModifierData *smd, int useRenderParams, float (*vertCos)[3], int isFinalCalc);
 struct DerivedMesh *subsurf_make_derived_from_derived(
                         struct DerivedMesh *dm,
                         struct SubsurfModifierData *smd,
index 824c1566100fd8950578b068b06629d28c5f3bee..61e38521cf5eed5ea3702c7f931f0d1e5d7f64df 100644 (file)
@@ -220,7 +220,6 @@ void bglVertex3f(float x, float y, float z) {}
 void bglEnd(void) {}
 
 /* booleanops.c */
-struct DispListMesh *NewBooleanMeshDLM(struct Object *ob, struct Object *ob_select, int int_op_type) { return 0; }
 struct DerivedMesh *NewBooleanDerivedMesh(struct Object *ob, struct Object *ob_select, int int_op_type) { return 0; }
 
 // bobj read/write debug messages
index f1285032802837ee18279add6de2c8b625f96fe2..dcf19128e5bc9fd241151b33b9200391f6a09d14 100644 (file)
 
 ///////////////////////////////////
 ///////////////////////////////////
-#define DERIVEDMESH_INITIAL_LAYERS 5
+
+MVert *dm_getVertArray(DerivedMesh *dm)
+{
+       MVert *mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
+
+       if (!mvert) {
+               mvert = CustomData_add_layer(&dm->vertData, CD_MVERT,
+                       CD_FLAG_TEMPORARY, NULL, dm->getNumVerts(dm));
+               dm->copyVertArray(dm, mvert);
+       }
+
+       return mvert;
+}
+
+MEdge *dm_getEdgeArray(DerivedMesh *dm)
+{
+       MEdge *medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
+
+       if (!medge) {
+               medge = CustomData_add_layer(&dm->edgeData, CD_MEDGE,
+                       CD_FLAG_TEMPORARY, NULL, dm->getNumEdges(dm));
+               dm->copyEdgeArray(dm, medge);
+       }
+
+       return medge;
+}
+
+MFace *dm_getFaceArray(DerivedMesh *dm)
+{
+       MFace *mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
+
+       if (!mface) {
+               mface = CustomData_add_layer(&dm->faceData, CD_MFACE,
+                       CD_FLAG_TEMPORARY, NULL, dm->getNumFaces(dm));
+               dm->copyFaceArray(dm, mface);
+       }
+
+       return mface;
+}
 
 MVert *dm_dupVertArray(DerivedMesh *dm)
 {
        MVert *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumVerts(dm),
                                 "dm_dupVertArray tmp");
 
-       if(tmp) dm->getVertArray(dm, tmp);
+       if(tmp) dm->copyVertArray(dm, tmp);
 
        return tmp;
 }
@@ -105,7 +143,7 @@ MEdge *dm_dupEdgeArray(DerivedMesh *dm)
        MEdge *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumEdges(dm),
                                 "dm_dupEdgeArray tmp");
 
-       if(tmp) dm->getEdgeArray(dm, tmp);
+       if(tmp) dm->copyEdgeArray(dm, tmp);
 
        return tmp;
 }
@@ -115,7 +153,7 @@ MFace *dm_dupFaceArray(DerivedMesh *dm)
        MFace *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumFaces(dm),
                                 "dm_dupFaceArray tmp");
 
-       if(tmp) dm->getFaceArray(dm, tmp);
+       if(tmp) dm->copyFaceArray(dm, tmp);
 
        return tmp;
 }
@@ -123,6 +161,9 @@ MFace *dm_dupFaceArray(DerivedMesh *dm)
 void DM_init_funcs(DerivedMesh *dm)
 {
        /* default function implementations */
+       dm->getVertArray = dm_getVertArray;
+       dm->getEdgeArray = dm_getEdgeArray;
+       dm->getFaceArray = dm_getFaceArray;
        dm->dupVertArray = dm_dupVertArray;
        dm->dupEdgeArray = dm_dupEdgeArray;
        dm->dupFaceArray = dm_dupFaceArray;
@@ -138,104 +179,111 @@ void DM_init_funcs(DerivedMesh *dm)
 void DM_init(DerivedMesh *dm,
              int numVerts, int numEdges, int numFaces)
 {
-       CustomData_init(&dm->vertData, DERIVEDMESH_INITIAL_LAYERS, numVerts,
-                       SUB_ELEMS_VERT);
-       CustomData_init(&dm->edgeData, DERIVEDMESH_INITIAL_LAYERS, numEdges,
-                       SUB_ELEMS_EDGE);
-       CustomData_init(&dm->faceData, DERIVEDMESH_INITIAL_LAYERS, numFaces,
-                       SUB_ELEMS_FACE);
+       CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, 0, NULL, numVerts);
+       CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, 0, NULL, numEdges);
+       CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, 0, NULL, numFaces);
 
-       CustomData_add_layer(&dm->vertData, LAYERTYPE_ORIGINDEX, 0, NULL);
-       CustomData_add_layer(&dm->edgeData, LAYERTYPE_ORIGINDEX, 0, NULL);
-       CustomData_add_layer(&dm->faceData, LAYERTYPE_ORIGINDEX, 0, NULL);
+       dm->numVertData = numVerts;
+       dm->numEdgeData = numEdges;
+       dm->numFaceData = numFaces;
 
        DM_init_funcs(dm);
+       
+       dm->needsFree = 1;
 }
 
 void DM_from_template(DerivedMesh *dm, DerivedMesh *source,
                       int numVerts, int numEdges, int numFaces)
 {
-       CustomData_from_template(&source->vertData, &dm->vertData, 0, numVerts);
-       CustomData_from_template(&source->edgeData, &dm->edgeData, 0, numEdges);
-       CustomData_from_template(&source->faceData, &dm->faceData, 0, numFaces);
+       CustomData_copy(&source->vertData, &dm->vertData, CD_MASK_DERIVEDMESH,
+                       CD_CALLOC, numVerts);
+       CustomData_copy(&source->edgeData, &dm->edgeData, CD_MASK_DERIVEDMESH,
+                       CD_CALLOC, numEdges);
+       CustomData_copy(&source->faceData, &dm->faceData, CD_MASK_DERIVEDMESH,
+                       CD_CALLOC, numFaces);
+
+       dm->numVertData = numVerts;
+       dm->numEdgeData = numEdges;
+       dm->numFaceData = numFaces;
 
        DM_init_funcs(dm);
+
+       dm->needsFree = 1;
 }
 
-void DM_release(DerivedMesh *dm)
+int DM_release(DerivedMesh *dm)
 {
-       CustomData_free(&dm->vertData);
-       CustomData_free(&dm->edgeData);
-       CustomData_free(&dm->faceData);
+       if (dm->needsFree) {
+               CustomData_free(&dm->vertData, dm->numVertData);
+               CustomData_free(&dm->edgeData, dm->numEdgeData);
+               CustomData_free(&dm->faceData, dm->numFaceData);
+
+               return 1;
+       }
+       else {
+               CustomData_free_temporary(&dm->vertData, dm->numVertData);
+               CustomData_free_temporary(&dm->edgeData, dm->numEdgeData);
+               CustomData_free_temporary(&dm->faceData, dm->numFaceData);
+
+               return 0;
+       }
 }
 
 void DM_to_mesh(DerivedMesh *dm, Mesh *me)
 {
        /* dm might depend on me, so we need to do everything with a local copy */
-       Mesh tmp_me = *me;
-       int numVerts = dm->getNumVerts(dm);
-
-       tmp_me.dvert = NULL;
-       tmp_me.tface = NULL;
-       tmp_me.mcol = NULL;
-
-       tmp_me.totvert = numVerts;
-       tmp_me.totedge = dm->getNumEdges(dm);
-       tmp_me.totface = dm->getNumFaces(dm);
-
-       tmp_me.mvert = dm->dupVertArray(dm);
-       tmp_me.medge = dm->dupEdgeArray(dm);
-       tmp_me.mface = dm->dupFaceArray(dm);
-
-       if(dm->getFaceDataArray(dm, LAYERTYPE_TFACE))
-               tmp_me.tface = MEM_dupallocN(dm->getFaceDataArray(dm,
-                                                                 LAYERTYPE_TFACE));
-       if(dm->getFaceDataArray(dm, LAYERTYPE_MCOL))
-               tmp_me.mcol = MEM_dupallocN(dm->getFaceDataArray(dm,
-                                                                LAYERTYPE_MCOL));
-       if(dm->getVertDataArray(dm, LAYERTYPE_MDEFORMVERT)) {
-               int i;
-               MDeformVert *dv;
+       Mesh tmp = *me;
+       int totvert, totedge, totface;
 
-               tmp_me.dvert = MEM_dupallocN(
-                                   dm->getVertDataArray(dm, LAYERTYPE_MDEFORMVERT));
+       memset(&tmp.vdata, 0, sizeof(tmp.vdata));
+       memset(&tmp.edata, 0, sizeof(tmp.edata));
+       memset(&tmp.fdata, 0, sizeof(tmp.fdata));
 
-               for(i = 0, dv = tmp_me.dvert; i < numVerts; ++i, ++dv)
-                       dv->dw = MEM_dupallocN(dv->dw);
-       }
+       totvert = tmp.totvert = dm->getNumVerts(dm);
+       totedge = tmp.totedge = dm->getNumEdges(dm);
+       totface = tmp.totface = dm->getNumFaces(dm);
 
-       if(me->mvert) MEM_freeN(me->mvert);
-       if(me->dvert) free_dverts(me->dvert, me->totvert);
-       if(me->mface) MEM_freeN(me->mface);
-       if(me->tface) MEM_freeN(me->tface);
-       if(me->mcol) MEM_freeN(me->mcol);
-       if(me->medge) MEM_freeN(me->medge);
+       CustomData_copy(&dm->vertData, &tmp.vdata, CD_MASK_MESH, CD_DUPLICATE, totvert);
+       CustomData_copy(&dm->edgeData, &tmp.edata, CD_MASK_MESH, CD_DUPLICATE, totedge);
+       CustomData_copy(&dm->faceData, &tmp.fdata, CD_MASK_MESH, CD_DUPLICATE, totface);
 
-       /* if the number of verts has changed, remove invalid data */
-       if(numVerts != me->totvert) {
-               if(me->msticky) MEM_freeN(me->msticky);
-               me->msticky = NULL;
+       /* not all DerivedMeshes store their verts/edges/faces in CustomData, so
+          we set them here in case they are missing */
+       if(!CustomData_has_layer(&tmp.vdata, CD_MVERT))
+               CustomData_add_layer(&tmp.vdata, CD_MVERT, 0, dm->dupVertArray(dm), totvert);
+       if(!CustomData_has_layer(&tmp.edata, CD_MEDGE))
+               CustomData_add_layer(&tmp.edata, CD_MEDGE, 0, dm->dupEdgeArray(dm), totedge);
+       if(!CustomData_has_layer(&tmp.fdata, CD_MFACE))
+               CustomData_add_layer(&tmp.fdata, CD_MFACE, 0, dm->dupFaceArray(dm), totface);
+
+       mesh_update_customdata_pointers(&tmp);
 
+       CustomData_free(&me->vdata, me->totvert);
+       CustomData_free(&me->edata, me->totedge);
+       CustomData_free(&me->fdata, me->totface);
+
+       /* if the number of verts has changed, remove invalid data */
+       if(tmp.totvert != me->totvert) {
                if(me->key) me->key->id.us--;
                me->key = NULL;
        }
 
-       *me = tmp_me;
+       *me = tmp;
 }
 
 void DM_add_vert_layer(DerivedMesh *dm, int type, int flag, void *layer)
 {
-       CustomData_add_layer(&dm->vertData, type, flag, layer);
+       CustomData_add_layer(&dm->vertData, type, flag, layer, dm->numVertData);
 }
 
 void DM_add_edge_layer(DerivedMesh *dm, int type, int flag, void *layer)
 {
-       CustomData_add_layer(&dm->edgeData, type, flag, layer);
+       CustomData_add_layer(&dm->edgeData, type, flag, layer, dm->numEdgeData);
 }
 
 void DM_add_face_layer(DerivedMesh *dm, int type, int flag, void *layer)
 {
-       CustomData_add_layer(&dm->faceData, type, flag, layer);
+       CustomData_add_layer(&dm->faceData, type, flag, layer, dm->numFaceData);
 }
 
 void *DM_get_vert_data(DerivedMesh *dm, int index, int type)
@@ -287,24 +335,21 @@ void DM_copy_vert_data(DerivedMesh *source, DerivedMesh *dest,
                        int source_index, int dest_index, int count)
 {
        CustomData_copy_data(&source->vertData, &dest->vertData,
-                            source_index, dest_index,
-                            count);
+                            source_index, dest_index, count);
 }
 
 void DM_copy_edge_data(DerivedMesh *source, DerivedMesh *dest,
                        int source_index, int dest_index, int count)
 {
        CustomData_copy_data(&source->edgeData, &dest->edgeData,
-                            source_index, dest_index,
-                            count);
+                            source_index, dest_index, count);
 }
 
 void DM_copy_face_data(DerivedMesh *source, DerivedMesh *dest,
                        int source_index, int dest_index, int count)
 {
        CustomData_copy_data(&source->faceData, &dest->faceData,
-                            source_index, dest_index,
-                            count);
+                            source_index, dest_index, count);
 }
 
 void DM_free_vert_data(struct DerivedMesh *dm, int index, int count)
@@ -348,618 +393,45 @@ void DM_interp_face_data(DerivedMesh *source, DerivedMesh *dest,
                          weights, (float*)vert_weights, count, dest_index);
 }
 
-typedef struct {
-       DerivedMesh dm;
-
-       Object *ob;
-       Mesh *me;
-       MVert *verts;
-       float *nors;
-       MCol *wpaintMCol;
-
-       int freeNors, freeVerts;
-} MeshDerivedMesh;
-
-static DispListMesh *meshDM_convertToDispListMesh(DerivedMesh *dm, int allowShared)
-{
-       MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
-       Mesh *me = mdm->me;
-       DispListMesh *dlm = MEM_callocN(sizeof(*dlm), "dlm");
-
-       dlm->totvert = me->totvert;
-       dlm->totedge = me->totedge;
-       dlm->totface = me->totface;
-       dlm->mvert = mdm->verts;
-       dlm->medge = me->medge;
-       dlm->mface = me->mface;
-       dlm->tface = me->tface;
-       dlm->mcol = me->mcol;
-       dlm->nors = mdm->nors;
-       dlm->dontFreeVerts = dlm->dontFreeOther = dlm->dontFreeNors = 1;
-
-       if (!allowShared) {
-               dlm->mvert = MEM_dupallocN(dlm->mvert);
-               if (dlm->nors) dlm->nors = MEM_dupallocN(dlm->nors);
-
-               dlm->dontFreeVerts = dlm->dontFreeNors = 0;
-       }
-
-       return dlm;
-}
-
-static void meshDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
-{
-       MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
-       Mesh *me = mdm->me;
-       int i;
-
-       if (me->totvert) {
-               for (i=0; i<me->totvert; i++) {
-                       DO_MINMAX(mdm->verts[i].co, min_r, max_r);
-               }
-       } else {
-               min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
-       }
-}
-
-static void meshDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
-{
-       MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
-       Mesh *me = mdm->me;
-       int i;
-
-       for (i=0; i<me->totvert; i++) {
-               cos_r[i][0] = mdm->verts[i].co[0];
-               cos_r[i][1] = mdm->verts[i].co[1];
-               cos_r[i][2] = mdm->verts[i].co[2];
-       }
-}
-
-static void meshDM_getVertCo(DerivedMesh *dm, int index, float co_r[3])
-{
-       MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
-
-       VECCOPY(co_r, mdm->verts[index].co);
-}
-
-static void meshDM_getVertNo(DerivedMesh *dm, int index, float no_r[3])
-{
-       MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
-       short *no = mdm->verts[index].no;
-
-       no_r[0] = no[0]/32767.f;
-       no_r[1] = no[1]/32767.f;
-       no_r[2] = no[2]/32767.f;
-}
-
-static void meshDM_drawVerts(DerivedMesh *dm)
-{
-       MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
-       Mesh *me = mdm->me;
-       int i;
-
-       glBegin(GL_POINTS);
-       for(i=0; i<me->totvert; i++) {
-               glVertex3fv(mdm->verts[i].co);
-       }
-       glEnd();
-}
-static void meshDM_drawUVEdges(DerivedMesh *dm)
-{
-       MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
-       Mesh *me = mdm->me;
-       int i;
-
-       if (me->tface) {
-               glBegin(GL_LINES);
-               for (i=0; i<me->totface; i++) {
-                       TFace *tf = &me->tface[i];
-
-                       if (!(tf->flag&TF_HIDE)) {
-                               glVertex2fv(tf->uv[0]);
-                               glVertex2fv(tf->uv[1]);
-
-                               glVertex2fv(tf->uv[1]);
-                               glVertex2fv(tf->uv[2]);
-
-                               if (!me->mface[i].v4) {
-                                       glVertex2fv(tf->uv[2]);
-                                       glVertex2fv(tf->uv[0]);
-                               } else {
-                                       glVertex2fv(tf->uv[2]);
-                                       glVertex2fv(tf->uv[3]);
-
-                                       glVertex2fv(tf->uv[3]);
-                                       glVertex2fv(tf->uv[0]);
-                               }
-                       }
-               }
-               glEnd();
-       }
-}
-static void meshDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
-{
-       MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
-       Mesh *me= mdm->me;
-       MEdge *medge= me->medge;
-       int i;
-               
-       glBegin(GL_LINES);
-       for(i=0; i<me->totedge; i++, medge++) {
-               if ((medge->flag&ME_EDGEDRAW) && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
-                       glVertex3fv(mdm->verts[medge->v1].co);
-                       glVertex3fv(mdm->verts[medge->v2].co);
-               }
-       }
-       glEnd();
-}
-static void meshDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
-{
-       MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
-       Mesh *me= mdm->me;
-       int i;
-               
-       glBegin(GL_LINES);
-       for (i=0; i<me->totedge; i++) {
-               if (!setDrawOptions || setDrawOptions(userData, i)) {
-                       glVertex3fv(mdm->verts[me->medge[i].v1].co);
-                       glVertex3fv(mdm->verts[me->medge[i].v2].co);
-               }
-       }
-       glEnd();
-}
-static void meshDM_drawLooseEdges(DerivedMesh *dm)
-{
-       MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
-       Mesh *me= mdm->me;
-       MEdge *medge= me->medge;
-       int i;
-
-       glBegin(GL_LINES);
-       for (i=0; i<me->totedge; i++, medge++) {
-               if (medge->flag&ME_LOOSEEDGE) {
-                       glVertex3fv(mdm->verts[medge->v1].co);
-                       glVertex3fv(mdm->verts[medge->v2].co);
-               }
-       }
-       glEnd();
-}
-static void meshDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
-{
-       MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
-       Mesh *me = mdm->me;
-       MVert *mvert= mdm->verts;
-       MFace *mface= me->mface;
-       float *nors = mdm->nors;
-       int a;
-       int glmode=-1, shademodel=-1, matnr=-1, drawCurrentMat=1;
-
-#define PASSVERT(index) {                                              \
-       if (shademodel==GL_SMOOTH) {                            \
-               short *no = mvert[index].no;                    \
-               glNormal3sv(no);                                                \
-       }                                                                                       \
-       glVertex3fv(mvert[index].co);   \
-}
-
-       glBegin(glmode=GL_QUADS);
-       for(a=0; a<me->totface; a++, mface++, nors+=3) {
-               int new_glmode, new_matnr, new_shademodel;
-                       
-               new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES;
-               new_matnr = mface->mat_nr+1;
-               new_shademodel = (mface->flag & ME_SMOOTH)?GL_SMOOTH:GL_FLAT;
-               
-               if (new_glmode!=glmode || new_matnr!=matnr || new_shademodel!=shademodel) {
-                       glEnd();
-
-                       drawCurrentMat = setMaterial(matnr=new_matnr);
-
-                       glShadeModel(shademodel=new_shademodel);
-                       glBegin(glmode=new_glmode);
-               } 
-               
-               if (drawCurrentMat) {
-                       if(shademodel==GL_FLAT) 
-                               glNormal3fv(nors);
-
-                       PASSVERT(mface->v1);
-                       PASSVERT(mface->v2);
-                       PASSVERT(mface->v3);
-                       if (mface->v4) {
-                               PASSVERT(mface->v4);
-                       }
-               }
-       }
-       glEnd();
-
-       glShadeModel(GL_FLAT);
-#undef PASSVERT
-}
-
-static void meshDM_drawFacesColored(DerivedMesh *dm, int useTwoSide, unsigned char *col1, unsigned char *col2)
-{
-       MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
-       Mesh *me= mdm->me;
-       MFace *mface= me->mface;
-       int a, glmode;
-       unsigned char *cp1, *cp2;
-
-       cp1= col1;
-       if(col2) {
-               cp2= col2;
-       } else {
-               cp2= NULL;
-               useTwoSide= 0;
-       }
-
-       /* there's a conflict here... twosided colors versus culling...? */
-       /* defined by history, only texture faces have culling option */
-       /* we need that as mesh option builtin, next to double sided lighting */
-       if(col1 && col2)
-               glEnable(GL_CULL_FACE);
-       
-       glShadeModel(GL_SMOOTH);
-       glBegin(glmode=GL_QUADS);
-       for(a=0; a<me->totface; a++, mface++, cp1+= 16) {
-               int new_glmode= mface->v4?GL_QUADS:GL_TRIANGLES;
-
-               if (new_glmode!=glmode) {
-                       glEnd();
-                       glBegin(glmode= new_glmode);
-               }
-                       
-               glColor3ub(cp1[3], cp1[2], cp1[1]);
-               glVertex3fv( mdm->verts[mface->v1].co );
-               glColor3ub(cp1[7], cp1[6], cp1[5]);
-               glVertex3fv( mdm->verts[mface->v2].co );
-               glColor3ub(cp1[11], cp1[10], cp1[9]);
-               glVertex3fv( mdm->verts[mface->v3].co );
-               if(mface->v4) {
-                       glColor3ub(cp1[15], cp1[14], cp1[13]);
-                       glVertex3fv( mdm->verts[mface->v4].co );
-               }
-                       
-               if(useTwoSide) {
-                       glColor3ub(cp2[11], cp2[10], cp2[9]);
-                       glVertex3fv( mdm->verts[mface->v3].co );
-                       glColor3ub(cp2[7], cp2[6], cp2[5]);
-                       glVertex3fv( mdm->verts[mface->v2].co );
-                       glColor3ub(cp2[3], cp2[2], cp2[1]);
-                       glVertex3fv( mdm->verts[mface->v1].co );
-                       if(mface->v4) {
-                               glColor3ub(cp2[15], cp2[14], cp2[13]);
-                               glVertex3fv( mdm->verts[mface->v4].co );
-                       }
-               }
-               if(col2) cp2+= 16;
-       }
-       glEnd();
-
-       glShadeModel(GL_FLAT);
-       glDisable(GL_CULL_FACE);
-}
-
-static void meshDM_drawFacesTex_common(DerivedMesh *dm, int (*drawParams)(TFace *tface, int matnr), int (*drawParamsMapped)(void *userData, int index), void *userData) 
-{
-       MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
-       Mesh *me = mdm->me;
-       MVert *mvert= mdm->verts;
-       MFace *mface= me->mface;
-       TFace *tface = me->tface;
-       float *nors = mdm->nors;
-       int i;
-
-       for (i=0; i<me->totface; i++) {
-               MFace *mf= &mface[i];
-               TFace *tf = tface?&tface[i]:NULL;
-               int flag;
-               unsigned char *cp= NULL;
-               
-               if (drawParams)
-                       flag = drawParams(tf, mf->mat_nr);
-               else
-                       flag = drawParamsMapped(userData, i);
-
-               if (flag==0) {
-                       continue;
-               } else if (flag==1) {
-                       if (mdm->wpaintMCol) {
-                               cp= (unsigned char*) &mdm->wpaintMCol[i*4];
-                       } else if (tf) {
-                               cp= (unsigned char*) tf->col;
-                       } else if (me->mcol) {
-                               cp= (unsigned char*) &me->mcol[i*4];
-                       }
-               }
-
-               if (!(mf->flag&ME_SMOOTH)) {
-                       glNormal3fv(&nors[i*3]);
-               }
-
-               glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
-               if (tf) glTexCoord2fv(tf->uv[0]);
-               if (cp) glColor3ub(cp[3], cp[2], cp[1]);
-               if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v1].no);
-               glVertex3fv(mvert[mf->v1].co);
-                       
-               if (tf) glTexCoord2fv(tf->uv[1]);
-               if (cp) glColor3ub(cp[7], cp[6], cp[5]);
-               if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v2].no);
-               glVertex3fv(mvert[mf->v2].co);
-
-               if (tf) glTexCoord2fv(tf->uv[2]);
-               if (cp) glColor3ub(cp[11], cp[10], cp[9]);
-               if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v3].no);
-               glVertex3fv(mvert[mf->v3].co);
-
-               if(mf->v4) {
-                       if (tf) glTexCoord2fv(tf->uv[3]);
-                       if (cp) glColor3ub(cp[15], cp[14], cp[13]);
-                       if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v4].no);
-                       glVertex3fv(mvert[mf->v4].co);
-               }
-               glEnd();
-       }
-}
-static void meshDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tface, int matnr)) 
-{
-       meshDM_drawFacesTex_common(dm, setDrawParams, NULL, NULL);
-}
-static void meshDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawParams)(void *userData, int index), void *userData) 
-{
-       meshDM_drawFacesTex_common(dm, NULL, setDrawParams, userData);
-}
-
-static void meshDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors) 
-{
-       MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
-       Mesh *me = mdm->me;
-       MVert *mvert= mdm->verts;
-       MFace *mface= me->mface;
-       float *nors= mdm->nors;
-       int i;
-
-       for (i=0; i<me->totface; i++) {
-               MFace *mf= &mface[i];
-               int drawSmooth = (mf->flag & ME_SMOOTH);
-
-               if (!setDrawOptions || setDrawOptions(userData, i, &drawSmooth)) {
-                       unsigned char *cp = NULL;
-
-                       if (useColors) {
-                               if (mdm->wpaintMCol) {
-                                       cp= (unsigned char*) &mdm->wpaintMCol[i*4];
-                               } else if (me->tface) {
-                                       cp= (unsigned char*) me->tface[i].col;
-                               } else if (me->mcol) {
-                                       cp= (unsigned char*) &me->mcol[i*4];
-                               }
-                       }
-
-                       glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
-                       glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
-
-                       if (!drawSmooth) {
-                               glNormal3fv(&nors[i*3]);
-
-                               if (cp) glColor3ub(cp[3], cp[2], cp[1]);
-                               glVertex3fv(mvert[mf->v1].co);
-                               if (cp) glColor3ub(cp[7], cp[6], cp[5]);
-                               glVertex3fv(mvert[mf->v2].co);
-                               if (cp) glColor3ub(cp[11], cp[10], cp[9]);
-                               glVertex3fv(mvert[mf->v3].co);
-                               if(mf->v4) {
-                                       if (cp) glColor3ub(cp[15], cp[14], cp[13]);
-                                       glVertex3fv(mvert[mf->v4].co);
-                               }
-                       } else {
-                               if (cp) glColor3ub(cp[3], cp[2], cp[1]);
-                               glNormal3sv(mvert[mf->v1].no);
-                               glVertex3fv(mvert[mf->v1].co);
-                               if (cp) glColor3ub(cp[7], cp[6], cp[5]);
-                               glNormal3sv(mvert[mf->v2].no);
-                               glVertex3fv(mvert[mf->v2].co);
-                               if (cp) glColor3ub(cp[11], cp[10], cp[9]);
-                               glNormal3sv(mvert[mf->v3].no);
-                               glVertex3fv(mvert[mf->v3].co);
-                               if(mf->v4) {
-                                       if (cp) glColor3ub(cp[15], cp[14], cp[13]);
-                                       glNormal3sv(mvert[mf->v4].no);
-                                       glVertex3fv(mvert[mf->v4].co);
-                               }
-                       }
-
-                       glEnd();
-               }
-       }
-}
-static int meshDM_getNumVerts(DerivedMesh *dm)
-{
-       MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
-       Mesh *me = mdm->me;
-
-       return me->totvert;
-}
-
-static int meshDM_getNumEdges(DerivedMesh *dm)
-{
-       MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
-       Mesh *me = mdm->me;
-
-       return me->totedge;
-}
-
-static int meshDM_getNumFaces(DerivedMesh *dm)
-{
-       MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
-       Mesh *me = mdm->me;
-
-       return me->totface;
-}
-
-void meshDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
-{
-       MVert *verts = ((MeshDerivedMesh *)dm)->verts;
-
-       *vert_r = verts[index];
-}
-
-void meshDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
-{
-       Mesh *me = ((MeshDerivedMesh *)dm)->me;
-
-       *edge_r = me->medge[index];
-}
-
-void meshDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
-{
-       Mesh *me = ((MeshDerivedMesh *)dm)->me;
-
-       *face_r = me->mface[index];
-}
-
-void meshDM_getVertArray(DerivedMesh *dm, MVert *vert_r)
-{
-       MeshDerivedMesh *mdm = (MeshDerivedMesh *)dm;
-       memcpy(vert_r, mdm->verts, sizeof(*vert_r) * mdm->me->totvert);
-}
-
-void meshDM_getEdgeArray(DerivedMesh *dm, MEdge *edge_r)
-{
-       MeshDerivedMesh *mdm = (MeshDerivedMesh *)dm;
-       memcpy(edge_r, mdm->me->medge, sizeof(*edge_r) * mdm->me->totedge);
-}
-
-void meshDM_getFaceArray(DerivedMesh *dm, MFace *face_r)
-{
-       MeshDerivedMesh *mdm = (MeshDerivedMesh *)dm;
-       memcpy(face_r, mdm->me->mface, sizeof(*face_r) * mdm->me->totface);
-}
-
-static void meshDM_release(DerivedMesh *dm)
+void DM_swap_face_data(DerivedMesh *dm, int index, int *corner_indices)
 {
-       MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
-
-       DM_release(dm);
-
-       if (mdm->wpaintMCol) MEM_freeN(mdm->wpaintMCol);
-       if (mdm->freeNors) MEM_freeN(mdm->nors);
-       if (mdm->freeVerts) MEM_freeN(mdm->verts);
-       MEM_freeN(mdm);
+       CustomData_swap(&dm->faceData, index, corner_indices);
 }
 
 static DerivedMesh *getMeshDerivedMesh(Mesh *me, Object *ob, float (*vertCos)[3])
 {
-       MeshDerivedMesh *mdm = MEM_callocN(sizeof(*mdm), "mdm");
+       DerivedMesh *dm = CDDM_from_mesh(me, ob);
+       int i, dofluidsim;
 
-       DM_init(&mdm->dm, me->totvert, me->totedge, me->totface);
+       dofluidsim = ((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) &&
+                     (ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN)&&
+                     (ob->fluidsimSettings->meshSurface) &&
+                     (1) && (!give_parteff(ob)) && // doesnt work together with particle systems!
+                     (me->totvert == ((Mesh *)(ob->fluidsimSettings->meshSurface))->totvert));
 
-       mdm->dm.getMinMax = meshDM_getMinMax;
+       if (vertCos && !dofluidsim)
+               CDDM_apply_vert_coords(dm, vertCos);
 
-       mdm->dm.convertToDispListMesh = meshDM_convertToDispListMesh;
-       mdm->dm.getNumVerts = meshDM_getNumVerts;
-       mdm->dm.getNumEdges = meshDM_getNumEdges;
-       mdm->dm.getNumFaces = meshDM_getNumFaces;
+       CDDM_calc_normals(dm);
 
-       mdm->dm.getVert = meshDM_getVert;
-       mdm->dm.getEdge = meshDM_getEdge;
-       mdm->dm.getFace = meshDM_getFace;
-       mdm->dm.getVertArray = meshDM_getVertArray;
-       mdm->dm.getEdgeArray = meshDM_getEdgeArray;
-       mdm->dm.getFaceArray = meshDM_getFaceArray;
-
-       mdm->dm.getVertCos = meshDM_getVertCos;
-       mdm->dm.getVertCo = meshDM_getVertCo;
-       mdm->dm.getVertNo = meshDM_getVertNo;
-
-       mdm->dm.drawVerts = meshDM_drawVerts;
-
-       mdm->dm.drawUVEdges = meshDM_drawUVEdges;
-       mdm->dm.drawEdges = meshDM_drawEdges;
-       mdm->dm.drawLooseEdges = meshDM_drawLooseEdges;
-       
-       mdm->dm.drawFacesSolid = meshDM_drawFacesSolid;
-       mdm->dm.drawFacesColored = meshDM_drawFacesColored;
-       mdm->dm.drawFacesTex = meshDM_drawFacesTex;
-       mdm->dm.drawMappedFaces = meshDM_drawMappedFaces;
-       mdm->dm.drawMappedFacesTex = meshDM_drawMappedFacesTex;
-
-       mdm->dm.drawMappedEdges = meshDM_drawMappedEdges;
-       mdm->dm.drawMappedFaces = meshDM_drawMappedFaces;
-
-       mdm->dm.release = meshDM_release;
-
-       /* add appropriate data layers (don't copy, just reference) */
-       if(me->msticky)
-               DM_add_vert_layer(&mdm->dm, LAYERTYPE_MSTICKY,
-                                 LAYERFLAG_NOFREE, me->msticky);
-       if(me->dvert)
-               DM_add_vert_layer(&mdm->dm, LAYERTYPE_MDEFORMVERT,
-                                 LAYERFLAG_NOFREE, me->dvert);
-
-       if(me->tface)
-               DM_add_face_layer(&mdm->dm, LAYERTYPE_TFACE,
-                                 LAYERFLAG_NOFREE, me->tface);
-       if(me->mcol)
-               DM_add_face_layer(&mdm->dm, LAYERTYPE_MCOL,
-                                 LAYERFLAG_NOFREE, me->mcol);
-
-               /* Works in conjunction with hack during modifier calc */
-       if ((G.f & G_WEIGHTPAINT) && ob==(G.scene->basact?G.scene->basact->object:NULL)) {
-               mdm->wpaintMCol = MEM_dupallocN(me->mcol);
-       }
-
-       mdm->ob = ob;
-       mdm->me = me;
-       mdm->verts = me->mvert;
-       mdm->nors = NULL;
-       mdm->freeNors = 0;
-       mdm->freeVerts = 0;
-
-       if((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) &&
-                (ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN)&&
-          (ob->fluidsimSettings->meshSurface) &&
-                (1) && (!give_parteff(ob)) && // doesnt work together with particle systems!
-                (me->totvert == ((Mesh *)(ob->fluidsimSettings->meshSurface))->totvert) ) {
-               // dont recompute for fluidsim mesh, use from readBobjgz
+       /* apply fluidsim normals */    
+       if (dofluidsim) {
+               // use normals from readBobjgz
                // TODO? check for modifiers!?
-               int i;
-               mesh_calc_normals(mdm->verts, me->totvert, me->mface, me->totface, &mdm->nors);
-               mdm->freeNors = 1;
+               MVert *fsvert = ob->fluidsimSettings->meshSurfNormals;
+               short (*normals)[3] = MEM_mallocN(sizeof(short)*3*me->totvert, "fluidsim nor");
+
                for (i=0; i<me->totvert; i++) {
-                       MVert *mv= &mdm->verts[i];
-                       MVert *fsv; 
-                       fsv = &ob->fluidsimSettings->meshSurfNormals[i];
-                       VECCOPY(mv->no, fsv->no);
+                       VECCOPY(normals[i], fsvert[i].no);
                        //mv->no[0]= 30000; mv->no[1]= mv->no[2]= 0; // DEBUG fixed test normals
                }
-       } else {
-               // recompute normally
 
-               if (vertCos) {
-                       int i;
+               CDDM_apply_vert_normals(dm, normals);
 
-                       /* copy the original verts to preserve flag settings; if this is too
-                        * costly, must at least use MEM_callocN to clear flags */
-                       mdm->verts = MEM_dupallocN( me->mvert );
-                       for (i=0; i<me->totvert; i++) {
-                               VECCOPY(mdm->verts[i].co, vertCos[i]);
-                       }
-                       mesh_calc_normals(mdm->verts, me->totvert, me->mface, me->totface, &mdm->nors);
-                       mdm->freeNors = 1;
-                       mdm->freeVerts = 1;
-               } else {
-                       // XXX this is kinda hacky because we shouldn't really be editing
-                       // the mesh here, however, we can't just call mesh_build_faceNormals(ob)
-                       // because in the case when a key is applied to a mesh the vertex normals
-                       // would never be correctly computed.
-                       mesh_calc_normals(mdm->verts, me->totvert, me->mface, me->totface, &mdm->nors);
-                       mdm->freeNors = 1;
-               }
-       } // fs TEST
+               MEM_freeN(normals);
+       }
 
-       return (DerivedMesh*) mdm;
+       return dm;
 }
 
 ///
@@ -1088,11 +560,11 @@ static void emDM_drawUVEdges(DerivedMesh *dm)
 {
        EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
        EditFace *efa;
-       TFace *tf;
+       MTFace *tf;
 
        glBegin(GL_LINES);
        for(efa= emdm->em->faces.first; efa; efa= efa->next) {
-               tf = CustomData_em_get(&emdm->em->fdata, efa->data, LAYERTYPE_TFACE);
+               tf = CustomData_em_get(&emdm->em->fdata, efa->data, CD_MTFACE);
 
                if(tf && !(tf->flag&TF_HIDE)) {
                        glVertex2fv(tf->uv[0]);
@@ -1315,813 +787,241 @@ void emDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
                        v1 = NULL;
                }
                if(ev == v2) {
-                       edge_r->v2 = i;
-                       v2 = NULL;
-               }
-       }
-}
-
-void emDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
-{
-       EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
-       EditFace *ef = em->faces.first;
-       EditVert *ev, *v1, *v2, *v3, *v4;
-       int i;
-
-       for(i = 0; i < index; ++i) ef = ef->next;
-
-       face_r->mat_nr = ef->mat_nr;
-       face_r->flag = ef->flag;
-
-       /* goddamn, we have to search all verts to find indices */
-       v1 = ef->v1;
-       v2 = ef->v2;
-       v3 = ef->v3;
-       v4 = ef->v4;
-       if(!v4) face_r->v4 = 0;
-
-       for(i = 0, ev = em->verts.first; v1 || v2 || v3 || v4;
-           i++, ev = ev->next) {
-               if(ev == v1) {
-                       face_r->v1 = i;
-                       v1 = NULL;
-               }
-               if(ev == v2) {
-                       face_r->v2 = i;
-                       v2 = NULL;
-               }
-               if(ev == v3) {
-                       face_r->v3 = i;
-                       v3 = NULL;
-               }
-               if(ev == v4) {
-                       face_r->v4 = i;
-                       v4 = NULL;
-               }
-       }
-
-       test_index_face(face_r, NULL, NULL, ef->v4?4:3);
-}
-
-void emDM_getVertArray(DerivedMesh *dm, MVert *vert_r)
-{
-       EditVert *ev = ((EditMeshDerivedMesh *)dm)->em->verts.first;
-
-       for( ; ev; ev = ev->next, ++vert_r) {
-               VECCOPY(vert_r->co, ev->co);
-
-               vert_r->no[0] = ev->no[0] * 32767.0;
-               vert_r->no[1] = ev->no[1] * 32767.0;
-               vert_r->no[2] = ev->no[2] * 32767.0;
-
-               /* TODO what to do with vert_r->flag and vert_r->mat_nr? */
-               vert_r->mat_nr = 0;
-               vert_r->flag = 0;
-       }
-}
-
-void emDM_getEdgeArray(DerivedMesh *dm, MEdge *edge_r)
-{
-       EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
-       EditEdge *ee = em->edges.first;
-       EditVert *ev, *prevev;
-       int i;
-
-       /* store vert indices in the prev pointer (kind of hacky) */
-       for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
-               ev->prev = (EditVert*) i++;
-
-       for( ; ee; ee = ee->next, ++edge_r) {
-               edge_r->crease = (unsigned char) (ee->crease*255.0f);
-               /* TODO what to do with edge_r->flag? */
-               edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
-               if (ee->seam) edge_r->flag |= ME_SEAM;
-               if (ee->sharp) edge_r->flag |= ME_SHARP;
-#if 0
-               /* this needs setup of f2 field */
-               if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
-#endif
-
-               edge_r->v1 = (int)ee->v1->prev;
-               edge_r->v2 = (int)ee->v2->prev;
-       }
-
-       /* restore prev pointers */
-       for(prevev = NULL, ev = em->verts.first; ev; prevev = ev, ev = ev->next)
-               ev->prev = prevev;
-}
-
-void emDM_getFaceArray(DerivedMesh *dm, MFace *face_r)
-{
-       EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
-       EditFace *ef = em->faces.first;
-       EditVert *ev, *prevev;
-       int i;
-
-       /* store vert indices in the prev pointer (kind of hacky) */
-       for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
-               ev->prev = (EditVert*) i++;
-
-       for( ; ef; ef = ef->next, ++face_r) {
-               face_r->mat_nr = ef->mat_nr;
-               face_r->flag = ef->flag;
-
-               face_r->v1 = (int)ef->v1->prev;
-               face_r->v2 = (int)ef->v2->prev;
-               face_r->v3 = (int)ef->v3->prev;
-               if(ef->v4) face_r->v4 = (int)ef->v4->prev;
-               else face_r->v4 = 0;
-
-               test_index_face(face_r, NULL, NULL, ef->v4?4:3);
-       }
-
-       /* restore prev pointers */
-       for(prevev = NULL, ev = em->verts.first; ev; prevev = ev, ev = ev->next)
-               ev->prev = prevev;
-}
-
-static void emDM_release(DerivedMesh *dm)
-{
-       EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-
-       DM_release(dm);
-
-       if (emdm->vertexCos) {
-               MEM_freeN(emdm->vertexCos);
-               MEM_freeN(emdm->vertexNos);
-               MEM_freeN(emdm->faceNos);
-       }
-
-       MEM_freeN(emdm);
-}
-
-static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, Object *ob,
-                                           float (*vertexCos)[3])
-{
-       EditMeshDerivedMesh *emdm = MEM_callocN(sizeof(*emdm), "emdm");
-
-       DM_init(&emdm->dm, BLI_countlist(&em->verts),
-                        BLI_countlist(&em->edges), BLI_countlist(&em->faces));
-
-       emdm->dm.getMinMax = emDM_getMinMax;
-
-       emdm->dm.getNumVerts = emDM_getNumVerts;
-       emdm->dm.getNumEdges = emDM_getNumEdges;
-       emdm->dm.getNumFaces = emDM_getNumFaces;
-
-       emdm->dm.getVert = emDM_getVert;
-       emdm->dm.getEdge = emDM_getEdge;
-       emdm->dm.getFace = emDM_getFace;
-       emdm->dm.getVertArray = emDM_getVertArray;
-       emdm->dm.getEdgeArray = emDM_getEdgeArray;
-       emdm->dm.getFaceArray = emDM_getFaceArray;
-
-       emdm->dm.foreachMappedVert = emDM_foreachMappedVert;
-       emdm->dm.foreachMappedEdge = emDM_foreachMappedEdge;
-       emdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter;
-
-       emdm->dm.drawEdges = emDM_drawEdges;
-       emdm->dm.drawMappedEdges = emDM_drawMappedEdges;
-       emdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp;
-       emdm->dm.drawMappedFaces = emDM_drawMappedFaces;
-       emdm->dm.drawUVEdges = emDM_drawUVEdges;
-
-       emdm->dm.release = emDM_release;
-       
-       emdm->em = em;
-       emdm->vertexCos = vertexCos;
-
-       if(CustomData_has_layer(&em->vdata, LAYERTYPE_MDEFORMVERT)) {
-               EditVert *eve;
-               int i;
-
-               DM_add_vert_layer(&emdm->dm, LAYERTYPE_MDEFORMVERT, 0, NULL);
-
-               for(eve = em->verts.first, i = 0; eve; eve = eve->next, ++i)
-                       DM_set_vert_data(&emdm->dm, i, LAYERTYPE_MDEFORMVERT,
-                                        CustomData_em_get(&em->vdata, eve->data, LAYERTYPE_MDEFORMVERT));
-       }
-
-       if(vertexCos) {
-               EditVert *eve, *preveve;
-               EditFace *efa;
-               int totface = BLI_countlist(&em->faces);
-               int i;
-
-               for (i=0,eve=em->verts.first; eve; eve= eve->next)
-                       eve->prev = (EditVert*) i++;
-
-               emdm->vertexNos = MEM_callocN(sizeof(*emdm->vertexNos)*i, "emdm_vno");
-               emdm->faceNos = MEM_mallocN(sizeof(*emdm->faceNos)*totface, "emdm_vno");
-
-               for(i=0, efa= em->faces.first; efa; i++, efa=efa->next) {
-                       float *v1 = vertexCos[(int) efa->v1->prev];
-                       float *v2 = vertexCos[(int) efa->v2->prev];
-                       float *v3 = vertexCos[(int) efa->v3->prev];
-                       float *no = emdm->faceNos[i];
-                       
-                       if(efa->v4) {
-                               float *v4 = vertexCos[(int) efa->v3->prev];
-
-                               CalcNormFloat4(v1, v2, v3, v4, no);
-                               VecAddf(emdm->vertexNos[(int) efa->v4->prev], emdm->vertexNos[(int) efa->v4->prev], no);
-                       }
-                       else {
-                               CalcNormFloat(v1, v2, v3, no);
-                       }
-
-                       VecAddf(emdm->vertexNos[(int) efa->v1->prev], emdm->vertexNos[(int) efa->v1->prev], no);
-                       VecAddf(emdm->vertexNos[(int) efa->v2->prev], emdm->vertexNos[(int) efa->v2->prev], no);
-                       VecAddf(emdm->vertexNos[(int) efa->v3->prev], emdm->vertexNos[(int) efa->v3->prev], no);
-               }
-
-               for(i=0, eve= em->verts.first; eve; i++, eve=eve->next) {
-                       float *no = emdm->vertexNos[i];
-                       /* following Mesh convention; we use vertex coordinate itself
-                        * for normal in this case */
-                       if (Normalise(no)==0.0) {
-                               VECCOPY(no, vertexCos[i]);
-                               Normalise(no);
-                       }
-               }
-
-               for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next)
-                       eve->prev = preveve;
-       }
-
-       return (DerivedMesh*) emdm;
-}
-
-///
-
-typedef struct {
-       DerivedMesh dm;
-
-       DispListMesh *dlm;
-} SSDerivedMesh;
-
-static void ssDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData)
-{
-       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
-       DispListMesh *dlm = ssdm->dlm;
-       int i;
-       int *index = dm->getVertDataArray(dm, LAYERTYPE_ORIGINDEX);
-
-       for (i=0; i<dlm->totvert; i++, index++) {
-               MVert *mv = &dlm->mvert[i];
-
-               if(*index != ORIGINDEX_NONE)
-                       func(userData, *index, mv->co, NULL, mv->no);
-       }
-}
-static void ssDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData)
-{
-       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
-       DispListMesh *dlm = ssdm->dlm;
-       int i;
-       int *index = dm->getEdgeDataArray(dm, LAYERTYPE_ORIGINDEX);
-
-       for (i=0; i<dlm->totedge; i++, index++) {
-               MEdge *med = &dlm->medge[i];
-
-               if(*index != ORIGINDEX_NONE)
-                       func(userData, *index, dlm->mvert[med->v1].co,
-                            dlm->mvert[med->v2].co);
-       }
-}
-static void ssDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) 
-{
-       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
-       DispListMesh *dlm = ssdm->dlm;
-       int i;
-       int *index = dm->getEdgeDataArray(dm, LAYERTYPE_ORIGINDEX);
-
-       glBegin(GL_LINES);
-       for(i=0; i<dlm->totedge; i++, index++) {
-               MEdge *med = &dlm->medge[i];
-
-               if(*index != ORIGINDEX_NONE
-                  && (!setDrawOptions || setDrawOptions(userData, *index))) {
-                       glVertex3fv(dlm->mvert[med->v1].co);
-                       glVertex3fv(dlm->mvert[med->v2].co);
-               }
-       }
-       glEnd();
-}
-
-static void ssDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData)
-{
-       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
-       DispListMesh *dlm = ssdm->dlm;
-       int i;
-       int *index = dm->getFaceDataArray(dm, LAYERTYPE_ORIGINDEX);
-
-       for (i=0; i<dlm->totface; i++, index++) {
-               MFace *mf = &dlm->mface[i];
-
-               if(*index != ORIGINDEX_NONE) {
-                       float cent[3];
-                       float no[3];
-
-                       VECCOPY(cent, dlm->mvert[mf->v1].co);
-                       VecAddf(cent, cent, dlm->mvert[mf->v2].co);
-                       VecAddf(cent, cent, dlm->mvert[mf->v3].co);
-
-                       if (mf->v4) {
-                               CalcNormFloat4(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, dlm->mvert[mf->v4].co, no);
-                               VecAddf(cent, cent, dlm->mvert[mf->v4].co);
-                               VecMulf(cent, 0.25f);
-                       } else {
-                               CalcNormFloat(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, no);
-                               VecMulf(cent, 0.33333333333f);
-                       }
-
-                       func(userData, *index, cent, no);
-               }
-       }
-}
-static void ssDM_drawVerts(DerivedMesh *dm)
-{
-       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
-       DispListMesh *dlm = ssdm->dlm;
-       MVert *mvert= dlm->mvert;
-       int i;
-
-       bglBegin(GL_POINTS);
-       for (i=0; i<dlm->totvert; i++) {
-               bglVertex3fv(mvert[i].co);
-       }
-       bglEnd();
-}
-static void ssDM_drawUVEdges(DerivedMesh *dm)
-{
-       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
-       DispListMesh *dlm = ssdm->dlm;
-       int i;
-
-       if (dlm->tface) {
-               glBegin(GL_LINES);
-               for (i=0; i<dlm->totface; i++) {
-                       TFace *tf = &dlm->tface[i];
-
-                       if (!(tf->flag&TF_HIDE)) {
-                               glVertex2fv(tf->uv[0]);
-                               glVertex2fv(tf->uv[1]);
-
-                               glVertex2fv(tf->uv[1]);
-                               glVertex2fv(tf->uv[2]);
-
-                               if (!dlm->mface[i].v4) {
-                                       glVertex2fv(tf->uv[2]);
-                                       glVertex2fv(tf->uv[0]);
-                               } else {
-                                       glVertex2fv(tf->uv[2]);
-                                       glVertex2fv(tf->uv[3]);
-
-                                       glVertex2fv(tf->uv[3]);
-                                       glVertex2fv(tf->uv[0]);
-                               }
-                       }
-               }
-               glEnd();
-       }
-}
-static void ssDM_drawLooseEdges(DerivedMesh *dm) 
-{
-       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
-       DispListMesh *dlm = ssdm->dlm;
-       MVert *mvert = dlm->mvert;
-       MEdge *medge= dlm->medge;
-       int i;
-
-       glBegin(GL_LINES);
-       for (i=0; i<dlm->totedge; i++, medge++) {
-               if (medge->flag&ME_LOOSEEDGE) {
-                       glVertex3fv(mvert[medge->v1].co); 
-                       glVertex3fv(mvert[medge->v2].co);
-               }
-       }
-       glEnd();
-}
-static void ssDM_drawEdges(DerivedMesh *dm, int drawLooseEdges) 
-{
-       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
-       DispListMesh *dlm = ssdm->dlm;
-       MVert *mvert= dlm->mvert;
-       MEdge *medge= dlm->medge;
-       int i;
-       
-       glBegin(GL_LINES);
-       for (i=0; i<dlm->totedge; i++, medge++) {
-               if ((medge->flag&ME_EDGEDRAW) && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
-                       glVertex3fv(mvert[medge->v1].co); 
-                       glVertex3fv(mvert[medge->v2].co);
-               }
-       }
-       glEnd();
-}
-static void ssDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
-{
-       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
-       DispListMesh *dlm = ssdm->dlm;
-       float *nors = dlm->nors;
-       int glmode=-1, shademodel=-1, matnr=-1, drawCurrentMat=1;
-       int i;
-
-#define PASSVERT(ind) {                                                \
-       if (shademodel==GL_SMOOTH)                              \
-               glNormal3sv(dlm->mvert[(ind)].no);      \
-       glVertex3fv(dlm->mvert[(ind)].co);              \
-}
-
-       glBegin(glmode=GL_QUADS);
-       for (i=0; i<dlm->totface; i++) {
-               MFace *mf= &dlm->mface[i];
-               int new_glmode = mf->v4?GL_QUADS:GL_TRIANGLES;
-               int new_shademodel = (mf->flag&ME_SMOOTH)?GL_SMOOTH:GL_FLAT;
-               int new_matnr = mf->mat_nr+1;
-               
-               if(new_glmode!=glmode || new_shademodel!=shademodel || new_matnr!=matnr) {
-                       glEnd();
-
-                       drawCurrentMat = setMaterial(matnr=new_matnr);
-
-                       glShadeModel(shademodel=new_shademodel);
-                       glBegin(glmode=new_glmode);
-               }
-               
-               if (drawCurrentMat) {
-                       if (shademodel==GL_FLAT)
-                               glNormal3fv(&nors[i*3]);
-                               
-                       PASSVERT(mf->v1);
-                       PASSVERT(mf->v2);
-                       PASSVERT(mf->v3);
-                       if (mf->v4)
-                               PASSVERT(mf->v4);
-               }
-       }
-       glEnd();
-       
-#undef PASSVERT
-}
-static void ssDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *vcols1, unsigned char *vcols2)
-{
-       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
-       DispListMesh *dlm = ssdm->dlm;
-       int i, lmode;
-       
-       glShadeModel(GL_SMOOTH);
-       if (vcols2) {
-               glEnable(GL_CULL_FACE);
-       } else {
-               useTwoSided = 0;
-       }
-               
-#define PASSVERT(vidx, fidx) {                                 \
-       unsigned char *col= &colbase[fidx*4];           \
-       glColor3ub(col[3], col[2], col[1]);                     \
-       glVertex3fv(dlm->mvert[(vidx)].co);                     \
-}
-
-       glBegin(lmode= GL_QUADS);
-       for (i=0; i<dlm->totface; i++) {
-               MFace *mf= &dlm->mface[i];
-               int nmode= mf->v4?GL_QUADS:GL_TRIANGLES;
-               unsigned char *colbase= &vcols1[i*16];
-               
-               if (nmode!=lmode) {
-                       glEnd();
-                       glBegin(lmode= nmode);
-               }
-               
-               PASSVERT(mf->v1, 0);
-               PASSVERT(mf->v2, 1);
-               PASSVERT(mf->v3, 2);
-               if (mf->v4)
-                       PASSVERT(mf->v4, 3);
-               
-               if (useTwoSided) {
-                       unsigned char *colbase= &vcols2[i*16];
-
-                       if (mf->v4)
-                               PASSVERT(mf->v4, 3);
-                       PASSVERT(mf->v3, 2);
-                       PASSVERT(mf->v2, 1);
-                       PASSVERT(mf->v1, 0);
-               }
-       }
-       glEnd();
-
-       if (vcols2)
-               glDisable(GL_CULL_FACE);
-       
-#undef PASSVERT
-}
-
-static void ssDM_drawFacesTex_common(DerivedMesh *dm, int (*drawParams)(TFace *tface, int matnr), int (*drawParamsMapped)(void *userData, int index), void *userData) 
-{
-       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
-       DispListMesh *dlm = ssdm->dlm;
-       MVert *mvert= dlm->mvert;
-       MFace *mface= dlm->mface;
-       TFace *tface = dlm->tface;
-       float *nors = dlm->nors;
-       int a;
-       int *index = dm->getFaceDataArray(dm, LAYERTYPE_ORIGINDEX);
-       
-       for (a=0; a<dlm->totface; a++, index++) {
-               MFace *mf= &mface[a];
-               TFace *tf = tface?&tface[a]:NULL;
-               int flag = 0;
-               unsigned char *cp= NULL;
-               
-               if (drawParams) {
-                       flag = drawParams(tf, mf->mat_nr);
-               }
-               else {
-                       if(*index != ORIGINDEX_NONE)
-                               flag = drawParamsMapped(userData, *index);
-               }
-
-               if (flag==0) {
-                       continue;
-               } else if (flag==1) {
-                       if (tf) {
-                               cp= (unsigned char*) tf->col;
-                       } else if (dlm->mcol) {
-                               cp= (unsigned char*) &dlm->mcol[a*4];
-                       }
-               }
-
-               if (!(mf->flag&ME_SMOOTH)) {
-                       glNormal3fv(&nors[a*3]);
-               }
-
-               glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
-               if (tf) glTexCoord2fv(tf->uv[0]);
-               if (cp) glColor3ub(cp[3], cp[2], cp[1]);
-               if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v1].no);
-               glVertex3fv((mvert+mf->v1)->co);
-                       
-               if (tf) glTexCoord2fv(tf->uv[1]);
-               if (cp) glColor3ub(cp[7], cp[6], cp[5]);
-               if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v2].no);
-               glVertex3fv((mvert+mf->v2)->co);
-
-               if (tf) glTexCoord2fv(tf->uv[2]);
-               if (cp) glColor3ub(cp[11], cp[10], cp[9]);
-               if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v3].no);
-               glVertex3fv((mvert+mf->v3)->co);
-
-               if(mf->v4) {
-                       if (tf) glTexCoord2fv(tf->uv[3]);
-                       if (cp) glColor3ub(cp[15], cp[14], cp[13]);
-                       if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v4].no);
-                       glVertex3fv((mvert+mf->v4)->co);
+                       edge_r->v2 = i;
+                       v2 = NULL;
                }
-               glEnd();
        }
 }
-static void ssDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tface, int matnr))
-{
-       ssDM_drawFacesTex_common(dm, setDrawParams, NULL, NULL);
-}
-static void ssDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawParams)(void *userData, int index), void *userData) 
-{
-       ssDM_drawFacesTex_common(dm, NULL, setDrawParams, userData);
-}
 
-static void ssDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors) 
+void emDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
 {
-       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
-       DispListMesh *dlm = ssdm->dlm;
-       MVert *mvert= dlm->mvert;
-       MFace *mface= dlm->mface;
-       float *nors = dlm->nors;
+       EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
+       EditFace *ef = em->faces.first;
+       EditVert *ev, *v1, *v2, *v3, *v4;
        int i;
-       int *index = dm->getFaceDataArray(dm, LAYERTYPE_ORIGINDEX);
-
-       for (i=0; i<dlm->totface; i++, index++) {
-               MFace *mf = &mface[i];
-               int drawSmooth = (mf->flag & ME_SMOOTH);
-
-               if(*index != ORIGINDEX_NONE
-                  && (!setDrawOptions
-                      || setDrawOptions(userData, *index, &drawSmooth))) {
-                       unsigned char *cp = NULL;
-
-                       if (useColors) {
-                               if (dlm->tface) {
-                                       cp= (unsigned char*) dlm->tface[i].col;
-                               } else if (dlm->mcol) {
-                                       cp= (unsigned char*) &dlm->mcol[i*4];
-                               }
-                       }
 
-                       glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
-                       glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
-
-                       if (!drawSmooth) {
-                               glNormal3fv(&nors[i*3]);
-
-                               if (cp) glColor3ub(cp[3], cp[2], cp[1]);
-                               glVertex3fv(mvert[mf->v1].co);
-                               if (cp) glColor3ub(cp[7], cp[6], cp[5]);
-                               glVertex3fv(mvert[mf->v2].co);
-                               if (cp) glColor3ub(cp[11], cp[10], cp[9]);
-                               glVertex3fv(mvert[mf->v3].co);
-                               if(mf->v4) {
-                                       if (cp) glColor3ub(cp[15], cp[14], cp[13]);
-                                       glVertex3fv(mvert[mf->v4].co);
-                               }
-                       } else {
-                               if (cp) glColor3ub(cp[3], cp[2], cp[1]);
-                               glNormal3sv(mvert[mf->v1].no);
-                               glVertex3fv(mvert[mf->v1].co);
-                               if (cp) glColor3ub(cp[7], cp[6], cp[5]);
-                               glNormal3sv(mvert[mf->v2].no);
-                               glVertex3fv(mvert[mf->v2].co);
-                               if (cp) glColor3ub(cp[11], cp[10], cp[9]);
-                               glNormal3sv(mvert[mf->v3].no);
-                               glVertex3fv(mvert[mf->v3].co);
-                               if(mf->v4) {
-                                       if (cp) glColor3ub(cp[15], cp[14], cp[13]);
-                                       glNormal3sv(mvert[mf->v4].no);
-                                       glVertex3fv(mvert[mf->v4].co);
-                               }
-                       }
+       for(i = 0; i < index; ++i) ef = ef->next;
 
-                       glEnd();
-               }
-       }
-}
-static void ssDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
-{
-       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
-       int i;
+       face_r->mat_nr = ef->mat_nr;
+       face_r->flag = ef->flag;
+
+       /* goddamn, we have to search all verts to find indices */
+       v1 = ef->v1;
+       v2 = ef->v2;
+       v3 = ef->v3;
+       v4 = ef->v4;
+       if(!v4) face_r->v4 = 0;
 
-       if (ssdm->dlm->totvert) {
-               for (i=0; i<ssdm->dlm->totvert; i++) {
-                       DO_MINMAX(ssdm->dlm->mvert[i].co, min_r, max_r);
+       for(i = 0, ev = em->verts.first; v1 || v2 || v3 || v4;
+           i++, ev = ev->next) {
+               if(ev == v1) {
+                       face_r->v1 = i;
+                       v1 = NULL;
+               }
+               if(ev == v2) {
+                       face_r->v2 = i;
+                       v2 = NULL;
+               }
+               if(ev == v3) {
+                       face_r->v3 = i;
+                       v3 = NULL;
+               }
+               if(ev == v4) {
+                       face_r->v4 = i;
+                       v4 = NULL;
                }
-       } else {
-               min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
        }
+
+       test_index_face(face_r, NULL, 0, ef->v4?4:3);
 }
 
-static void ssDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
+void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
 {
-       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
-       int i;
+       EditVert *ev = ((EditMeshDerivedMesh *)dm)->em->verts.first;
 
-       for (i=0; i<ssdm->dlm->totvert; i++) {
-               cos_r[i][0] = ssdm->dlm->mvert[i].co[0];
-               cos_r[i][1] = ssdm->dlm->mvert[i].co[1];
-               cos_r[i][2] = ssdm->dlm->mvert[i].co[2];
-       }
-}
+       for( ; ev; ev = ev->next, ++vert_r) {
+               VECCOPY(vert_r->co, ev->co);
 
-static int ssDM_getNumVerts(DerivedMesh *dm)
-{
-       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
+               vert_r->no[0] = ev->no[0] * 32767.0;
+               vert_r->no[1] = ev->no[1] * 32767.0;
+               vert_r->no[2] = ev->no[2] * 32767.0;
 
-       return ssdm->dlm->totvert;
+               /* TODO what to do with vert_r->flag and vert_r->mat_nr? */
+               vert_r->mat_nr = 0;
+               vert_r->flag = 0;
+       }
 }
 
-static int ssDM_getNumEdges(DerivedMesh *dm)
+void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
 {
-       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
+       EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
+       EditEdge *ee = em->edges.first;
+       EditVert *ev, *prevev;
+       int i;
 
-       return ssdm->dlm->totedge;
-}
+       /* store vert indices in the prev pointer (kind of hacky) */
+       for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
+               ev->prev = (EditVert*) i++;
 
-static int ssDM_getNumFaces(DerivedMesh *dm)
-{
-       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
+       for( ; ee; ee = ee->next, ++edge_r) {
+               edge_r->crease = (unsigned char) (ee->crease*255.0f);
+               /* TODO what to do with edge_r->flag? */
+               edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
+               if (ee->seam) edge_r->flag |= ME_SEAM;
+               if (ee->sharp) edge_r->flag |= ME_SHARP;
+#if 0
+               /* this needs setup of f2 field */
+               if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
+#endif
 
-       return ssdm->dlm->totface;
-}
+               edge_r->v1 = (int)ee->v1->prev;
+               edge_r->v2 = (int)ee->v2->prev;
+       }
 
-void ssDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
-{
-       *vert_r = ((SSDerivedMesh *)dm)->dlm->mvert[index];
+       /* restore prev pointers */
+       for(prevev = NULL, ev = em->verts.first; ev; prevev = ev, ev = ev->next)
+               ev->prev = prevev;
 }
 
-void ssDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
+void emDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
 {
-       *edge_r = ((SSDerivedMesh *)dm)->dlm->medge[index];
-}
+       EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
+       EditFace *ef = em->faces.first;
+       EditVert *ev, *prevev;
+       int i;
 
-void ssDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
-{
-       *face_r = ((SSDerivedMesh *)dm)->dlm->mface[index];
-}
+       /* store vert indices in the prev pointer (kind of hacky) */
+       for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
+               ev->prev = (EditVert*) i++;
 
-void ssDM_getVertArray(DerivedMesh *dm, MVert *vert_r)
-{
-       SSDerivedMesh *ssdm = (SSDerivedMesh *)dm;
-       memcpy(vert_r, ssdm->dlm->mvert, sizeof(*vert_r) * ssdm->dlm->totvert);
-}
+       for( ; ef; ef = ef->next, ++face_r) {
+               face_r->mat_nr = ef->mat_nr;
+               face_r->flag = ef->flag;
 
-void ssDM_getEdgeArray(DerivedMesh *dm, MEdge *edge_r)
-{
-       SSDerivedMesh *ssdm = (SSDerivedMesh *)dm;
-       memcpy(edge_r, ssdm->dlm->medge, sizeof(*edge_r) * ssdm->dlm->totedge);
-}
+               face_r->v1 = (int)ef->v1->prev;
+               face_r->v2 = (int)ef->v2->prev;
+               face_r->v3 = (int)ef->v3->prev;
+               if(ef->v4) face_r->v4 = (int)ef->v4->prev;
+               else face_r->v4 = 0;
 
-void ssDM_getFaceArray(DerivedMesh *dm, MFace *face_r)
-{
-       SSDerivedMesh *ssdm = (SSDerivedMesh *)dm;
-       memcpy(face_r, ssdm->dlm->mface, sizeof(*face_r) * ssdm->dlm->totface);
+               test_index_face(face_r, NULL, 0, ef->v4?4:3);
+       }
+
+       /* restore prev pointers */
+       for(prevev = NULL, ev = em->verts.first; ev; prevev = ev, ev = ev->next)
+               ev->prev = prevev;
 }
 
-static DispListMesh *ssDM_convertToDispListMesh(DerivedMesh *dm, int allowShared)
+static void emDM_release(DerivedMesh *dm)
 {
-       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
+       EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
 
-       if (allowShared) {
-               return displistmesh_copyShared(ssdm->dlm);
-       } else {
-               return displistmesh_copy(ssdm->dlm);
+       if (DM_release(dm)) {
+               if (emdm->vertexCos) {
+                       MEM_freeN(emdm->vertexCos);
+                       MEM_freeN(emdm->vertexNos);
+                       MEM_freeN(emdm->faceNos);
+               }
+
+               MEM_freeN(emdm);
        }
 }
 
-static void ssDM_release(DerivedMesh *dm)
+static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, Object *ob,
+                                           float (*vertexCos)[3])
 {
-       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
+       EditMeshDerivedMesh *emdm = MEM_callocN(sizeof(*emdm), "emdm");
 
-       DM_release(dm);
+       DM_init(&emdm->dm, BLI_countlist(&em->verts),
+                        BLI_countlist(&em->edges), BLI_countlist(&em->faces));
 
-       displistmesh_free(ssdm->dlm);
+       emdm->dm.getMinMax = emDM_getMinMax;
 
-       MEM_freeN(dm);
-}
+       emdm->dm.getNumVerts = emDM_getNumVerts;
+       emdm->dm.getNumEdges = emDM_getNumEdges;
+       emdm->dm.getNumFaces = emDM_getNumFaces;
 
-DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm, float (*vertexCos)[3])
-{
-       SSDerivedMesh *ssdm = MEM_callocN(sizeof(*ssdm), "ssdm");
+       emdm->dm.getVert = emDM_getVert;
+       emdm->dm.getEdge = emDM_getEdge;
+       emdm->dm.getFace = emDM_getFace;
+       emdm->dm.copyVertArray = emDM_copyVertArray;
+       emdm->dm.copyEdgeArray = emDM_copyEdgeArray;
+       emdm->dm.copyFaceArray = emDM_copyFaceArray;
+
+       emdm->dm.foreachMappedVert = emDM_foreachMappedVert;
+       emdm->dm.foreachMappedEdge = emDM_foreachMappedEdge;
+       emdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter;
 
-       DM_init(&ssdm->dm, dlm->totvert, dlm->totedge, dlm->totface);
+       emdm->dm.drawEdges = emDM_drawEdges;
+       emdm->dm.drawMappedEdges = emDM_drawMappedEdges;
+       emdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp;
+       emdm->dm.drawMappedFaces = emDM_drawMappedFaces;
+       emdm->dm.drawUVEdges = emDM_drawUVEdges;
 
-       ssdm->dm.getMinMax = ssDM_getMinMax;
+       emdm->dm.release = emDM_release;
+       
+       emdm->em = em;
+       emdm->vertexCos = vertexCos;
 
-       ssdm->dm.getNumVerts = ssDM_getNumVerts;
-       ssdm->dm.getNumEdges = ssDM_getNumEdges;
-       ssdm->dm.getNumFaces = ssDM_getNumFaces;
+       if(CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) {
+               EditVert *eve;
+               int i;
 
-       ssdm->dm.getVert = ssDM_getVert;
-       ssdm->dm.getEdge = ssDM_getEdge;
-       ssdm->dm.getFace = ssDM_getFace;
-       ssdm->dm.getVertArray = ssDM_getVertArray;
-       ssdm->dm.getEdgeArray = ssDM_getEdgeArray;
-       ssdm->dm.getFaceArray = ssDM_getFaceArray;
+               DM_add_vert_layer(&emdm->dm, CD_MDEFORMVERT, 0, NULL);
 
-       ssdm->dm.convertToDispListMesh = ssDM_convertToDispListMesh;
+               for(eve = em->verts.first, i = 0; eve; eve = eve->next, ++i)
+                       DM_set_vert_data(&emdm->dm, i, CD_MDEFORMVERT,
+                                        CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT));
+       }
 
-       ssdm->dm.getVertCos = ssDM_getVertCos;
+       if(vertexCos) {
+               EditVert *eve, *preveve;
+               EditFace *efa;
+               int totface = BLI_countlist(&em->faces);
+               int i;
 
-       ssdm->dm.drawVerts = ssDM_drawVerts;
+               for (i=0,eve=em->verts.first; eve; eve= eve->next)
+                       eve->prev = (EditVert*) i++;
 
-       ssdm->dm.drawUVEdges = ssDM_drawUVEdges;
-       ssdm->dm.drawEdges = ssDM_drawEdges;
-       ssdm->dm.drawLooseEdges = ssDM_drawLooseEdges;
-       
-       ssdm->dm.drawFacesSolid = ssDM_drawFacesSolid;
-       ssdm->dm.drawFacesColored = ssDM_drawFacesColored;
-       ssdm->dm.drawFacesTex = ssDM_drawFacesTex;
-       ssdm->dm.drawMappedFaces = ssDM_drawMappedFaces;
-       ssdm->dm.drawMappedFacesTex = ssDM_drawMappedFacesTex;
+               emdm->vertexNos = MEM_callocN(sizeof(*emdm->vertexNos)*i, "emdm_vno");
+               emdm->faceNos = MEM_mallocN(sizeof(*emdm->faceNos)*totface, "emdm_vno");
 
-               /* EM functions */
-       
-       ssdm->dm.foreachMappedVert = ssDM_foreachMappedVert;
-       ssdm->dm.foreachMappedEdge = ssDM_foreachMappedEdge;
-       ssdm->dm.foreachMappedFaceCenter = ssDM_foreachMappedFaceCenter;
-       
-       ssdm->dm.drawMappedEdges = ssDM_drawMappedEdges;
-       ssdm->dm.drawMappedEdgesInterp = NULL; // no way to implement this one
-       
-       ssdm->dm.release = ssDM_release;
-       
-       ssdm->dlm = dlm;
+               for(i=0, efa= em->faces.first; efa; i++, efa=efa->next) {
+                       float *v1 = vertexCos[(int) efa->v1->prev];
+                       float *v2 = vertexCos[(int) efa->v2->prev];
+                       float *v3 = vertexCos[(int) efa->v3->prev];
+                       float *no = emdm->faceNos[i];
+                       
+                       if(efa->v4) {
+                               float *v4 = vertexCos[(int) efa->v3->prev];
 
-       if (vertexCos) {
-               int i;
+                               CalcNormFloat4(v1, v2, v3, v4, no);
+                               VecAddf(emdm->vertexNos[(int) efa->v4->prev], emdm->vertexNos[(int) efa->v4->prev], no);
+                       }
+                       else {
+                               CalcNormFloat(v1, v2, v3, no);
+                       }
 
-               for (i=0; i<dlm->totvert; i++) {
-                       VECCOPY(dlm->mvert[i].co, vertexCos[i]);
+                       VecAddf(emdm->vertexNos[(int) efa->v1->prev], emdm->vertexNos[(int) efa->v1->prev], no);
+                       VecAddf(emdm->vertexNos[(int) efa->v2->prev], emdm->vertexNos[(int) efa->v2->prev], no);
+                       VecAddf(emdm->vertexNos[(int) efa->v3->prev], emdm->vertexNos[(int) efa->v3->prev], no);
                }
 
-               if (dlm->nors && !dlm->dontFreeNors) {
-                       MEM_freeN(dlm->nors);
-                       dlm->nors = 0;
+               for(i=0, eve= em->verts.first; eve; i++, eve=eve->next) {
+                       float *no = emdm->vertexNos[i];
+                       /* following Mesh convention; we use vertex coordinate itself
+                        * for normal in this case */
+                       if (Normalise(no)==0.0) {
+                               VECCOPY(no, vertexCos[i]);
+                               Normalise(no);
+                       }
                }
 
-               mesh_calc_normals(dlm->mvert, dlm->totvert, dlm->mface, dlm->totface, &dlm->nors);
+               for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next)
+                       eve->prev = preveve;
        }
 
-       return (DerivedMesh*) ssdm;
+       return (DerivedMesh*) emdm;
 }
 
 #ifdef WITH_VERSE
@@ -2251,11 +1151,11 @@ void vDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
                }
        }
 
-       test_index_face(face_r, NULL, NULL, vface->vvert3?4:3);
+       test_index_face(face_r, NULL, 0, vface->vvert3?4:3);
 }
 
 /* fill array of mvert */
-void vDM_getVertArray(DerivedMesh *dm, MVert *vert_r)
+void vDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
 {
        VerseVert *vvert = ((VDerivedMesh *)dm)->vertex_layer->dl.lb.first;
 
@@ -2272,12 +1172,12 @@ void vDM_getVertArray(DerivedMesh *dm, MVert *vert_r)
 }
 
 /* dummy function, edges arent supported in verse mesh */
-void vDM_getEdgeArray(DerivedMesh *dm, MEdge *edge_r)
+void vDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
 {
 }
 
 /* fill array of mfaces */
-void vDM_getFaceArray(DerivedMesh *dm, MFace *face_r)
+void vDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
 {
        VerseFace *vface = ((VDerivedMesh*)dm)->polygon_layer->dl.lb.first;
        VerseVert *vvert = ((VDerivedMesh*)dm)->vertex_layer->dl.lb.first;
@@ -2297,124 +1197,8 @@ void vDM_getFaceArray(DerivedMesh *dm, MFace *face_r)
                if(vface->vvert3) face_r->v4 = vface->vvert3->tmp.index;
                else face_r->v4 = 0;
 
-               test_index_face(face_r, NULL, NULL, vface->vvert3?4:3);
-       }
-}
-
-/* create diplist mesh from verse mesh */
-static DispListMesh* vDM_convertToDispListMesh(DerivedMesh *dm, int allowShared)
-{
-       VDerivedMesh *vdm = (VDerivedMesh*)dm;
-       DispListMesh *dlm = MEM_callocN(sizeof(*dlm), "dlm");
-       struct VerseVert *vvert;
-       struct VerseFace *vface;
-       struct MVert *mvert=NULL;
-       struct MFace *mface=NULL;
-       float *norms;
-       unsigned int i;
-       EdgeHash *edges;
-
-       if(!vdm->vertex_layer || !vdm->polygon_layer) {
-               dlm->totvert = 0;
-               dlm->totedge = 0;
-               dlm->totface = 0;
-               dlm->dontFreeVerts = dlm->dontFreeOther = dlm->dontFreeNors = 0;
-
-               return dlm;
-       };
-       
-       /* number of vertexes, edges and faces */
-       dlm->totvert = vdm->vertex_layer->dl.da.count;
-       dlm->totface = vdm->polygon_layer->dl.da.count;
-
-       /* create dynamic array of mverts */
-       mvert = (MVert*)MEM_mallocN(sizeof(MVert)*dlm->totvert, "dlm verts");
-       dlm->mvert = mvert;
-       vvert = (VerseVert*)vdm->vertex_layer->dl.lb.first;
-       i = 0;
-       while(vvert) {
-               VECCOPY(mvert->co, vdm->verts ? vvert->cos : vvert->co);
-               VECCOPY(mvert->no, vvert->no);
-               mvert->mat_nr = 0;
-               mvert->flag = 0;
-
-               vvert->tmp.index = i++;
-               mvert++;
-               vvert = vvert->next;
-       }
-
-       edges = BLI_edgehash_new();
-
-       /* create dynamic array of faces */
-       mface = (MFace*)MEM_mallocN(sizeof(MFace)*dlm->totface, "dlm faces");
-       dlm->mface = mface;
-       vface = (VerseFace*)vdm->polygon_layer->dl.lb.first;
-       i = 0;
-       while(vface) {
-               mface->v1 = vface->vvert0->tmp.index;
-               mface->v2 = vface->vvert1->tmp.index;
-               mface->v3 = vface->vvert2->tmp.index;
-               if(!BLI_edgehash_haskey(edges, mface->v1, mface->v2))
-                       BLI_edgehash_insert(edges, mface->v1, mface->v2, NULL);
-               if(!BLI_edgehash_haskey(edges, mface->v2, mface->v3))
-                       BLI_edgehash_insert(edges, mface->v2, mface->v3, NULL);
-               if(vface->vvert3) {
-                       mface->v4 = vface->vvert3->tmp.index;
-                       if(!BLI_edgehash_haskey(edges, mface->v3, mface->v4))
-                               BLI_edgehash_insert(edges, mface->v3, mface->v4, NULL);
-                       if(!BLI_edgehash_haskey(edges, mface->v4, mface->v1))
-                               BLI_edgehash_insert(edges, mface->v4, mface->v1, NULL);
-               } else {
-                       mface->v4 = 0;
-                       if(!BLI_edgehash_haskey(edges, mface->v3, mface->v1))
-                               BLI_edgehash_insert(edges, mface->v3, mface->v1, NULL);
-               }
-
-               mface->pad = 0;
-               mface->mat_nr = 0;
-               mface->flag = 0;
-               mface->edcode = 0;
-
-               test_index_face(mface, NULL, NULL, vface->vvert3?4:3);
-
-               mface++;
-               vface = vface->next;
-       }
-
-       dlm->totedge = BLI_edgehash_size(edges);
-
-       if(dlm->totedge) {
-               EdgeHashIterator *i;
-               MEdge *medge = dlm->medge = (MEdge *)MEM_mallocN(sizeof(MEdge)*dlm->totedge, "mesh_from_verse edge");
-
-               for(i = BLI_edgehashIterator_new(edges); !BLI_edgehashIterator_isDone(i); BLI_edgehashIterator_step(i), ++medge) {
-                       BLI_edgehashIterator_getKey(i, (int*)&medge->v1, (int*)&medge->v2);
-                       medge->crease = medge->pad = medge->flag = 0;
-               }
-               BLI_edgehashIterator_free(i);
-       }
-
-       BLI_edgehash_free(edges, NULL);
-
-       /* textures and verex colors aren't supported yet */
-       dlm->tface = NULL;
-       dlm->mcol = NULL;
-
-       /* faces normals */
-       norms = (float*)MEM_mallocN(sizeof(float)*3*dlm->totface, "dlm norms");
-       dlm->nors = norms;
-
-       vface = (VerseFace*)vdm->polygon_layer->dl.lb.first;
-       while(vface){
-               VECCOPY(norms, vface->no);
-               norms += 3;
-               vface = vface->next;
+               test_index_face(face_r, NULL, 0, vface->vvert3?4:3);
        }
-
-       /* free everything, nothing is shared */
-       dlm->dontFreeVerts = dlm->dontFreeOther = dlm->dontFreeNors = 0;
-
-       return dlm;
 }
 
 /* return coordination of vertex with index ... I suppose, that it will
@@ -2566,7 +1350,7 @@ static void vDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
 }
 
 /* thsi function should draw mesh with mapped texture, but it isn't supported yet */
-static void vDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(struct TFace *tface, int matnr))
+static void vDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
 {
        VDerivedMesh *vdm = (VDerivedMesh*)dm;
        struct VerseFace *vface;
@@ -2675,10 +1459,10 @@ static void vDM_release(DerivedMesh *dm)
 {
        VDerivedMesh *vdm = (VDerivedMesh*)dm;
 
-       DM_release(dm);
-
-       if(vdm->verts) MEM_freeN(vdm->verts);
-       MEM_freeN(vdm);
+       if (DM_release(dm)) {
+               if(vdm->verts) MEM_freeN(vdm->verts);
+               MEM_freeN(vdm);
+       }
 }
 
 /* create derived mesh from verse mesh ... it is used in object mode, when some other client can
@@ -2706,16 +1490,14 @@ DerivedMesh *derivedmesh_from_versemesh(VNode *vnode, float (*vertexCos)[3])
        vdm->dm.getVert = vDM_getVert;
        vdm->dm.getEdge = vDM_getEdge;
        vdm->dm.getFace = vDM_getFace;
-       vdm->dm.getVertArray = vDM_getVertArray;
-       vdm->dm.getEdgeArray = vDM_getEdgeArray;
-       vdm->dm.getFaceArray = vDM_getFaceArray;
+       vdm->dm.copyVertArray = vDM_copyVertArray;
+       vdm->dm.copyEdgeArray = vDM_copyEdgeArray;
+       vdm->dm.copyFaceArray = vDM_copyFaceArray;
        
        vdm->dm.foreachMappedVert = vDM_foreachMappedVert;
        vdm->dm.foreachMappedEdge = vDM_foreachMappedEdge;
        vdm->dm.foreachMappedFaceCenter = vDM_foreachMappedFaceCenter;
 
-       vdm->dm.convertToDispListMesh = vDM_convertToDispListMesh;
-
        vdm->dm.getVertCos = vDM_getVertCos;
        vdm->dm.getVertCo = vDM_getVertCo;
        vdm->dm.getVertNo = vDM_getVertNo;
@@ -2865,14 +1647,14 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
 #ifdef WITH_VERSE
                        if(me->vnode) *deform_r = derivedmesh_from_versemesh(me->vnode, deformedVerts);
                        else {
-                               *deform_r = CDDM_from_mesh(me);
+                               *deform_r = CDDM_from_mesh(me, ob);
                                if(deformedVerts) {
                                        CDDM_apply_vert_coords(*deform_r, deformedVerts);
                                        CDDM_calc_normals(*deform_r);
                                }
                        }
 #else
-                       *deform_r = CDDM_from_mesh(me);
+                       *deform_r = CDDM_from_mesh(me, ob);
                        if(deformedVerts) {
                                CDDM_apply_vert_coords(*deform_r, deformedVerts);
                                CDDM_calc_normals(*deform_r);
@@ -2954,7 +1736,7 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
                                        CDDM_calc_normals(dm);
                                }
                        } else {
-                               dm = CDDM_from_mesh(me);
+                               dm = CDDM_from_mesh(me, ob);
 
                                if(deformedVerts) {
                                        CDDM_apply_vert_coords(dm, deformedVerts);
@@ -2999,14 +1781,14 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
                if(me->vnode)
                        *final_r = derivedmesh_from_versemesh(me->vnode, deformedVerts);
                else {
-                       *final_r = CDDM_from_mesh(me);
+                       *final_r = CDDM_from_mesh(me, ob);
                        if(deformedVerts) {
                                CDDM_apply_vert_coords(*final_r, deformedVerts);
                                CDDM_calc_normals(*final_r);
                        }
                }
 #else
-               *final_r = CDDM_from_mesh(me);
+               *final_r = CDDM_from_mesh(me, ob);
                if(deformedVerts) {
                        CDDM_apply_vert_coords(*final_r, deformedVerts);
                        CDDM_calc_normals(*final_r);
@@ -3254,10 +2036,12 @@ static void clear_mesh_caches(Object *ob)
        freedisplist(&ob->disp);
 
        if (ob->derivedFinal) {
+               ob->derivedFinal->needsFree = 1;
                ob->derivedFinal->release(ob->derivedFinal);
                ob->derivedFinal= NULL;
        }
        if (ob->derivedDeform) {
+               ob->derivedDeform->needsFree = 1;
                ob->derivedDeform->release(ob->derivedDeform);
                ob->derivedDeform= NULL;
        }
@@ -3277,21 +2061,27 @@ static void mesh_build_data(Object *ob)
 
                if( (G.f & G_WEIGHTPAINT) && ob==obact ) {
                        MCol *mcol = me->mcol;
-                       TFace *tface =  me->tface;
+                       MCol *wpcol = (MCol*)calc_weightpaint_colors(ob);
 
-                       me->mcol = (MCol*) calc_weightpaint_colors(ob);
-                       if(me->tface) {
-                               me->tface = MEM_dupallocN(me->tface);
-                               mcol_to_tface(me, 1);
+                       /* ugly hack here, we replace mcol with weight paint colors, then
+                          CDDM_from_mesh duplicates it, and uses that instead of mcol */
+                       if (mcol) {
+                               CustomData_set_layer(&me->fdata, CD_MCOL, NULL);
+                               CustomData_free_layer(&me->fdata, CD_MCOL, me->totface);
                        }
 
+                       CustomData_add_layer(&me->fdata, CD_MCOL, CD_FLAG_NOFREE, wpcol, me->totface);
+                       me->mcol= wpcol;
+
                        mesh_calc_modifiers(ob, NULL, &ob->derivedDeform, &ob->derivedFinal, 0, 1,
                                            needMapping);
 
-                       if(me->mcol) MEM_freeN(me->mcol);
-                       if(me->tface) MEM_freeN(me->tface);
-                       me->mcol = mcol;
-                       me->tface = tface;
+                       CustomData_free_layer(&me->fdata, CD_MCOL, me->totface);
+                       if (wpcol) MEM_freeN(wpcol);
+
+                       if (mcol)
+                               me->mcol= CustomData_add_layer(&me->fdata, CD_MCOL, 0, mcol, me->totface);
+                       me->mcol= mcol;
                } else {
                        mesh_calc_modifiers(ob, NULL, &ob->derivedDeform,
                                            &ob->derivedFinal, 0, 1, needMapping);
@@ -3302,6 +2092,9 @@ static void mesh_build_data(Object *ob)
                ob->derivedFinal->getMinMax(ob->derivedFinal, min, max);
 
                boundbox_set_from_min_max(mesh_get_bb(ob->data), min, max);
+
+               ob->derivedFinal->needsFree = 0;
+               ob->derivedDeform->needsFree = 0;
        }
 }
 
@@ -3315,11 +2108,13 @@ static void editmesh_build_data(void)
 
        if (em->derivedFinal) {
                if (em->derivedFinal!=em->derivedCage) {
+                       em->derivedFinal->needsFree = 1;
                        em->derivedFinal->release(em->derivedFinal);
                }
                em->derivedFinal = NULL;
        }
        if (em->derivedCage) {
+               em->derivedCage->needsFree = 1;
                em->derivedCage->release(em->derivedCage);
                em->derivedCage = NULL;
        }
@@ -3331,9 +2126,12 @@ static void editmesh_build_data(void)
        em->derivedFinal->getMinMax(em->derivedFinal, min, max);
 
        boundbox_set_from_min_max(mesh_get_bb(G.obedit->data), min, max);
+
+       em->derivedFinal->needsFree = 0;
+       em->derivedCage->needsFree = 0;
 }
 
-void makeDispListMesh(Object *ob)
+void makeDerivedMesh(Object *ob)
 {
        if (ob==G.obedit) {
                editmesh_build_data();
@@ -3351,23 +2149,19 @@ void makeDispListMesh(Object *ob)
 
 /***/
 
-DerivedMesh *mesh_get_derived_final(Object *ob, int *needsFree_r)
+DerivedMesh *mesh_get_derived_final(Object *ob)
 {
-       if (!ob->derivedFinal) {
+       if (!ob->derivedFinal)
                mesh_build_data(ob);
-       }
 
-       *needsFree_r = 0;
        return ob->derivedFinal;
 }
 
-DerivedMesh *mesh_get_derived_deform(Object *ob, int *needsFree_r)
+DerivedMesh *mesh_get_derived_deform(Object *ob)
 {
-       if (!ob->derivedDeform) {
+       if (!ob->derivedDeform)
                mesh_build_data(ob);
-       } 
 
-       *needsFree_r = 0;
        return ob->derivedDeform;
 }
 
@@ -3390,7 +2184,7 @@ DerivedMesh *mesh_create_derived_render(Object *ob)
                if(final->getNumVerts(final) == m->totvert &&
                   final->getNumFaces(final) == m->totface) {
                        for(i=0; i<m->totvert; ++i)
-                               memcpy(&m->mvert[i], CustomData_get(&final->vertData, i, LAYERTYPE_MVERT), sizeof(MVert));
+                               memcpy(&m->mvert[i], CustomData_get(&final->vertData, i, CD_MVERT), sizeof(MVert));
 
                        final->release(final);
                        
@@ -3398,7 +2192,7 @@ DerivedMesh *mesh_create_derived_render(Object *ob)
                        multires_set_level(ob,m);
                        final= getMeshDerivedMesh(m,ob,NULL);
                }
-       }       
+       }
 
        return final;
 }
@@ -3432,10 +2226,8 @@ DerivedMesh *mesh_create_derived_no_deform_render(Object *ob, float (*vertCos)[3
 
 /***/
 
-DerivedMesh *editmesh_get_derived_cage_and_final(DerivedMesh **final_r, int *cageNeedsFree_r, int *finalNeedsFree_r)
+DerivedMesh *editmesh_get_derived_cage_and_final(DerivedMesh **final_r)
 {
-       *cageNeedsFree_r = *finalNeedsFree_r = 0;
-
        if (!G.editMesh->derivedCage)
                editmesh_build_data();
 
@@ -3443,10 +2235,8 @@ DerivedMesh *editmesh_get_derived_cage_and_final(DerivedMesh **final_r, int *cag
        return G.editMesh->derivedCage;
 }
 
-DerivedMesh *editmesh_get_derived_cage(int *needsFree_r)
+DerivedMesh *editmesh_get_derived_cage(void)
 {
-       *needsFree_r = 0;
-
        if (!G.editMesh->derivedCage)
                editmesh_build_data();
 
@@ -3490,13 +2280,12 @@ float *mesh_get_mapped_verts_nors(Object *ob)
        Mesh *me= ob->data;
        DerivedMesh *dm;
        float *vertexcosnos;
-       int needsFree;
        
        /* lets prevent crashing... */
        if(ob->type!=OB_MESH || me->totvert==0)
                return NULL;
        
-       dm= mesh_get_derived_final(ob, &needsFree);
+       dm= mesh_get_derived_final(ob);
        vertexcosnos= MEM_callocN(6*sizeof(float)*me->totvert, "vertexcosnos map");
        
        if(dm->foreachMappedVert) {
@@ -3512,7 +2301,7 @@ float *mesh_get_mapped_verts_nors(Object *ob)
                }
        }
        
-       if (needsFree) dm->release(dm);
+       dm->release(dm);
        return vertexcosnos;
 }
 
@@ -3531,14 +2320,14 @@ float *mesh_get_mapped_verts_nors(Object *ob)
 void writeBobjgz(char *filename, struct Object *ob, int useGlobalCoords, int append, float time) 
 {
        char debugStrBuffer[256];
-       int wri,i,j;
+       int wri,i,j,totvert,totface;
        float wrf;
        gzFile gzf;
-       DispListMesh *dlm = NULL;
        DerivedMesh *dm;
        float vec[3];
        float rotmat[3][3];
-       MFace *mface = NULL;
+       MVert *mvert;
+       MFace *mface;
        //if(append)return; // DEBUG
 
        if(!ob->data || (ob->type!=OB_MESH)) {
@@ -3562,8 +2351,11 @@ void writeBobjgz(char *filename, struct Object *ob, int useGlobalCoords, int app
 
        dm = mesh_create_derived_render(ob);
        //dm = mesh_create_derived_no_deform(ob,NULL);
-       dlm = dm->convertToDispListMesh(dm, 1);
-       mface = dlm->mface;
+
+       mvert = dm->getVertArray(dm);
+       mface = dm->getFaceArray(dm);
+       totvert = dm->getNumVerts(dm);
+       totface = dm->getNumFaces(dm);
 
        // write time value for appended anim mesh
        if(append) {
@@ -3572,10 +2364,11 @@ void writeBobjgz(char *filename, struct Object *ob, int useGlobalCoords, int app
 
        // continue with verts/norms
        if(sizeof(wri)!=4) { snprintf(debugStrBuffer,256,"Writing GZ_BOBJ, Invalid int size %d...\n", wri); elbeemDebugOut(debugStrBuffer); return; } // paranoia check
-       wri = dlm->totvert;
+       wri = dm->getNumVerts(dm);
+       mvert = dm->getVertArray(dm);
        gzwrite(gzf, &wri, sizeof(wri));
        for(i=0; i<wri;i++) {
-               VECCOPY(vec, dlm->mvert[i].co);
+               VECCOPY(vec, mvert[i].co);
                if(useGlobalCoords) { Mat4MulVecfl(ob->obmat, vec); }
                for(j=0; j<3; j++) {
                        wrf = vec[j]; 
@@ -3584,11 +2377,11 @@ void writeBobjgz(char *filename, struct Object *ob, int useGlobalCoords, int app
        }
 
        // should be the same as Vertices.size
-       wri = dlm->totvert;
+       wri = totvert;
        gzwrite(gzf, &wri, sizeof(wri));
        EulToMat3(ob->rot, rotmat);
        for(i=0; i<wri;i++) {
-               VECCOPY(vec, dlm->mvert[i].no);
+               VECCOPY(vec, mvert[i].no);
                Normalise(vec);
                if(useGlobalCoords) { Mat3MulVecfl(rotmat, vec); }
                for(j=0; j<3; j++) {
@@ -3604,12 +2397,12 @@ void writeBobjgz(char *filename, struct Object *ob, int useGlobalCoords, int app
        
                // compute no. of triangles 
                wri = 0;
-               for(i=0; i<dlm->totface; i++) {
+               for(i=0; i<totface; i++) {
                        wri++;
                        if(mface[i].v4) { wri++; }
                }
                gzwrite(gzf, &wri, sizeof(wri));
-               for(i=0; i<dlm->totface; i++) {
+               for(i=0; i<totface; i++) {
 
                        int face[4];
                        face[0] = mface[i].v1;
@@ -3617,15 +2410,15 @@ void writeBobjgz(char *filename, struct Object *ob, int useGlobalCoords, int app
                        face[2] = mface[i].v3;
                        face[3] = mface[i].v4;
                        //snprintf(debugStrBuffer,256,"F %s %d = %d,%d,%d,%d \n",ob->id.name, i, face[0],face[1],face[2],face[3] ); elbeemDebugOut(debugStrBuffer);
-                       //VecSubf(side1, dlm->mvert[face[1]].co,dlm->mvert[face[0]].co);
-                       //VecSubf(side2, dlm->mvert[face[2]].co,dlm->mvert[face[0]].co);
+                       //VecSubf(side1, mvert[face[1]].co,mvert[face[0]].co);
+                       //VecSubf(side2, mvert[face[2]].co,mvert[face[0]].co);
                        //Crossf(norm1,side1,side2);
                        gzwrite(gzf, &(face[0]), sizeof( face[0] )); 
                        gzwrite(gzf, &(face[1]), sizeof( face[1] )); 
                        gzwrite(gzf, &(face[2]), sizeof( face[2] )); 
                        if(face[3]) { 
-                               //VecSubf(side1, dlm->mvert[face[2]].co,dlm->mvert[face[0]].co);
-                               //VecSubf(side2, dlm->mvert[face[3]].co,dlm->mvert[face[0]].co);
+                               //VecSubf(side1, mvert[face[2]].co,mvert[face[0]].co);
+                               //VecSubf(side2, mvert[face[3]].co,mvert[face[0]].co);
                                //Crossf(norm2,side1,side2);
                                //inpf = Inpf(norm1,norm2);
                                //if(inpf>0.) {
@@ -3641,11 +2434,10 @@ void writeBobjgz(char *filename, struct Object *ob, int useGlobalCoords, int app
                }
        }
 
-       snprintf(debugStrBuffer,256,"Done. #Vertices: %d, #Triangles: %d\n", dlm->totvert, dlm->totface ); 
+       snprintf(debugStrBuffer,256,"Done. #Vertices: %d, #Triangles: %d\n", totvert, totface ); 
        elbeemDebugOut(debugStrBuffer);
        
        gzclose( gzf );
-       if(dlm) displistmesh_free(dlm);
        dm->release(dm);
 }
 
@@ -3654,36 +2446,38 @@ void initElbeemMesh(struct Object *ob,
                int *numTriangles, int **triangles,
                int useGlobalCoords) 
 {
-       DispListMesh *dlm = NULL;
        DerivedMesh *dm = NULL;
-       MFace *mface = NULL;
-       int countTris=0, i;
+       MVert *mvert;
+       MFace *mface;
+       int countTris=0, i, totvert, totface;
        float *verts;
        int *tris;
 
        dm = mesh_create_derived_render(ob);
        //dm = mesh_create_derived_no_deform(ob,NULL);
        if(!dm) { *numVertices = *numTriangles = 0; *triangles=NULL; *vertices=NULL; }
-       dlm = dm->convertToDispListMesh(dm, 1);
-       if(!dlm) { dm->release(dm); *numVertices = *numTriangles = 0; *triangles=NULL; *vertices=NULL; }
-       mface = dlm->mface;
-
-       *numVertices = dlm->totvert;
-       verts = MEM_callocN( dlm->totvert*3*sizeof(float), "elbeemmesh_vertices");
-       for(i=0; i<dlm->totvert; i++) {
-               VECCOPY( &verts[i*3], dlm->mvert[i].co);
+
+       mvert = dm->getVertArray(dm);
+       mface = dm->getFaceArray(dm);
+       totvert = dm->getNumVerts(dm);
+       totface = dm->getNumFaces(dm);
+
+       *numVertices = totvert;
+       verts = MEM_callocN( totvert*3*sizeof(float), "elbeemmesh_vertices");
+       for(i=0; i<totvert; i++) {
+               VECCOPY( &verts[i*3], mvert[i].co);
                if(useGlobalCoords) { Mat4MulVecfl(ob->obmat, &verts[i*3]); }
        }
        *vertices = verts;
 
-       for(i=0; i<dlm->totface; i++) {
+       for(i=0; i<totface; i++) {
                countTris++;
                if(mface[i].v4) { countTris++; }
        }
        *numTriangles = countTris;
        tris = MEM_callocN( countTris*3*sizeof(int), "elbeemmesh_triangles");
        countTris = 0;
-       for(i=0; i<dlm->totface; i++) {
+       for(i=0; i<totface; i++) {
                int face[4];
                face[0] = mface[i].v1;
                face[1] = mface[i].v2;
@@ -3703,7 +2497,6 @@ void initElbeemMesh(struct Object *ob,
        }
        *triangles = tris;
 
-       if(dlm) displistmesh_free(dlm);
        dm->release(dm);
 }
 
@@ -3735,14 +2528,16 @@ Mesh* readBobjgz(char *filename, Mesh *orgmesh, float* bbstart, float *bbsize) /
        newmesh->mvert= NULL;
        newmesh->medge= NULL;
        newmesh->mface= NULL;
-       newmesh->tface= NULL;
-       newmesh->dface= NULL;
+       newmesh->mtface= NULL;
 
        newmesh->dvert = NULL;
 
        newmesh->mcol= NULL;
        newmesh->msticky= NULL;
        newmesh->texcomesh= NULL;
+       memset(&newmesh->vdata, 0, sizeof(newmesh->vdata));
+       memset(&newmesh->edata, 0, sizeof(newmesh->edata));
+       memset(&newmesh->fdata, 0, sizeof(newmesh->fdata));
 
        newmesh->key= NULL;
        newmesh->totface = 0;
@@ -3764,7 +2559,7 @@ Mesh* readBobjgz(char *filename, Mesh *orgmesh, float* bbstart, float *bbsize) /
        //if(sizeof(wri)!=4) { snprintf(debugStrBuffer,256,"Reading GZ_BOBJ, Invalid int size %d...\n", wri); return NULL; } // paranoia check
        gotBytes = gzread(gzf, &wri, sizeof(wri));
        newmesh->totvert = wri;
-       newmesh->mvert = MEM_callocN(sizeof(MVert)*newmesh->totvert, "fluidsimDerivedMesh_bobjvertices");
+       newmesh->mvert = CustomData_add_layer(&newmesh->vdata, CD_MVERT, 0, NULL, newmesh->totvert);
        if(debugBobjRead){ snprintf(debugStrBuffer,256,"#vertices %d ", newmesh->totvert); elbeemDebugOut(debugStrBuffer); } //DEBUG
        for(i=0; i<newmesh->totvert;i++) {
                //if(debugBobjRead) snprintf(debugStrBuffer,256,"V %d = ",i);
@@ -3780,7 +2575,7 @@ Mesh* readBobjgz(char *filename, Mesh *orgmesh, float* bbstart, float *bbsize) /
        gotBytes = gzread(gzf, &wri, sizeof(wri));
        if(wri != newmesh->totvert) {
                // complain #vertices has to be equal to #normals, reset&abort
-               MEM_freeN(newmesh->mvert);
+               CustomData_free_layer(&newmesh->vdata, CD_MVERT, newmesh->totvert);
                MEM_freeN(newmesh);
                snprintf(debugStrBuffer,256,"Reading GZ_BOBJ, #normals=%d, #vertices=%d, aborting...\n", wri,newmesh->totvert );
                return NULL;
@@ -3800,7 +2595,7 @@ Mesh* readBobjgz(char *filename, Mesh *orgmesh, float* bbstart, float *bbsize) /
        /* compute no. of triangles */
        gotBytes = gzread(gzf, &wri, sizeof(wri));
        newmesh->totface = wri;
-       newmesh->mface = MEM_callocN(sizeof(MFace)*newmesh->totface, "fluidsimDerivedMesh_bobjfaces");
+       newmesh->mface = CustomData_add_layer(&newmesh->fdata, CD_MFACE, 0, NULL, newmesh->totface);
        if(debugBobjRead){ snprintf(debugStrBuffer,256,"#faces %d ", newmesh->totface); elbeemDebugOut(debugStrBuffer); } //DEBUG
        fsface = newmesh->mface;
        for(i=0; i<newmesh->totface; i++) {
@@ -3925,9 +2720,9 @@ void loadFluidsimMesh(Object *srcob, int useRenderParams)
                Mesh *freeFsMesh = srcob->fluidsimSettings->meshSurface;
 
                // similar to free_mesh(...) , but no things like unlink...
-               if(freeFsMesh->mvert){ MEM_freeN(freeFsMesh->mvert); freeFsMesh->mvert=NULL; }
-               if(freeFsMesh->medge){ MEM_freeN(freeFsMesh->medge); freeFsMesh->medge=NULL; }
-               if(freeFsMesh->mface){ MEM_freeN(freeFsMesh->mface); freeFsMesh->mface=NULL; }
+               CustomData_free(&freeFsMesh->vdata, freeFsMesh->totvert);
+               CustomData_free(&freeFsMesh->edata, freeFsMesh->totedge);
+               CustomData_free(&freeFsMesh->fdata, freeFsMesh->totface);
                MEM_freeN(freeFsMesh);
                
                if(srcob->data == srcob->fluidsimSettings->meshSurface)
@@ -4067,13 +2862,13 @@ void fluidsimGetAxisAlignedBB(struct Mesh *mesh, float obmat[][4],
                else {           newmesh = *bbmesh; }
 
                newmesh->totvert = 8;
-               if(!newmesh->mvert) newmesh->mvert = MEM_callocN(sizeof(MVert)*newmesh->totvert, "fluidsimBBMesh_bobjvertices");
+               if(!newmesh->mvert) newmesh->mvert = CustomData_add_layer(&newmesh->vdata, CD_MVERT, 0, NULL, newmesh->totvert);
                for(i=0; i<8; i++) {
                        for(j=0; j<3; j++) newmesh->mvert[i].co[j] = start[j]; 
                }
 
                newmesh->totface = 6;
-               if(!newmesh->mface) newmesh->mface = MEM_callocN(sizeof(MFace)*newmesh->totface, "fluidsimBBMesh_bobjfaces");
+               if(!newmesh->mface) newmesh->mface = CustomData_add_layer(&newmesh->fdata, CD_MFACE, 0, NULL, newmesh->totface);
 
                *bbmesh = newmesh;
        }
index 4d58e2b46b6638d6ee70e5cfe3db38122c6d3178..162cca32b725bae8bbadc7c61fcd2dbeb6065e9a 100644 (file)
@@ -403,7 +403,6 @@ static void vertex_duplilist(ListBase *lb, Scene *sce, Object *par)
        Base *base;
        float vec[3], no[3], pmat[4][4];
        int lay, totvert, a;
-       int dmNeedsFree;
        DerivedMesh *dm;
        
        Mat4CpyMat4(pmat, par->obmat);
@@ -411,9 +410,9 @@ static void vertex_duplilist(ListBase *lb, Scene *sce, Object *par)
        lay= G.scene->lay;
        
        if(par==G.obedit)
-               dm= editmesh_get_derived_cage(&dmNeedsFree);
+               dm= editmesh_get_derived_cage();
        else
-               dm = mesh_get_derived_deform(par, &dmNeedsFree);
+               dm = mesh_get_derived_deform(par);
        
        totvert = dm->getNumVerts(dm);
 
@@ -455,8 +454,7 @@ static void vertex_duplilist(ListBase *lb, Scene *sce, Object *par)
                base= base->next;
        }
 
-       if (dmNeedsFree)
-               dm->release(dm);
+       dm->release(dm);
 }
 
 static void particle_duplilist(ListBase *lb, Scene *sce, Object *par, PartEff *paf)
index 21f833fb32f39828067779c78fc38fc630410f3b..7fb3f9a260b3cd99ce8e953ef130a9de77242a6e 100644 (file)
@@ -699,7 +699,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
                        }
                        /* if we have a DerivedMesh, only use dverts if it has them */
                        if(dm)
-                               if(dm->getVertData(dm, 0, LAYERTYPE_MDEFORMVERT))
+                               if(dm->getVertData(dm, 0, CD_MDEFORMVERT))
                                        use_dverts = 1;
                                else use_dverts = 0;
                        else if(dverts) use_dverts = 1;
@@ -734,7 +734,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
                Mat4MulVecfl(premat, co);
                
                if(use_dverts || armature_def_nr >= 0) {
-                       if(dm) dvert = dm->getVertData(dm, i, LAYERTYPE_MDEFORMVERT);
+                       if(dm) dvert = dm->getVertData(dm, i, CD_MDEFORMVERT);
                        else if(i < target_totvert) dvert = dverts + i;
                        else dvert = NULL;
                } else
index faa2018029040579936246d08278c9ce684afd82..78ee6bb40e2912775721816b66cb540b325540ee 100644 (file)
@@ -40,6 +40,7 @@
 #include "BKE_customdata.h"
 #include "BKE_DerivedMesh.h"
 #include "BKE_displist.h"
+#include "BKE_global.h"
 #include "BKE_mesh.h"
 #include "BKE_utildefines.h"
 
 
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
 
 #include "MEM_guardedalloc.h"
 
 #include <string.h>
 #include <limits.h>
 
+typedef struct {
+       DerivedMesh dm;
+
+       /* these point to data in the DerivedMesh custom data layers,
+          they are only here for efficiency and convenience **/
+       MVert *mvert;
+       MEdge *medge;
+       MFace *mface;
+} CDDerivedMesh;
 
 /**************** DerivedMesh interface functions ****************/
 static int cdDM_getNumVerts(DerivedMesh *dm)
 {
-       return dm->vertData.numElems;
+       return dm->numVertData;
 }
 
-static int cdDM_getNumFaces(DerivedMesh *dm)
+static int cdDM_getNumEdges(DerivedMesh *dm)
 {
-       return dm->faceData.numElems;
+       return dm->numEdgeData;
 }
 
-static int cdDM_getNumEdges(DerivedMesh *dm)
+static int cdDM_getNumFaces(DerivedMesh *dm)
 {
-       return dm->edgeData.numElems;
+       return dm->numFaceData;
 }
 
 static void cdDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
 {
-       *vert_r = *CDDM_get_vert(dm, index);
+       CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
+       *vert_r = cddm->mvert[index];
 }
 
 static void cdDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
 {
-       *edge_r = *CDDM_get_edge(dm, index);
+       CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
+       *edge_r = cddm->medge[index];
 }
 
 static void cdDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
 {
-       *face_r = *CDDM_get_face(dm, index);
-}
-
-static void cdDM_getVertArray(DerivedMesh *dm, MVert *vert_r)
-{
-       memcpy(vert_r, CDDM_get_verts(dm), sizeof(*vert_r) * dm->getNumVerts(dm));
-}
-
-static void cdDM_getEdgeArray(DerivedMesh *dm, MEdge *edge_r)
-{
-       memcpy(edge_r, CDDM_get_edges(dm), sizeof(*edge_r) * dm->getNumEdges(dm));
+       CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
+       *face_r = cddm->mface[index];
 }
 
-static void cdDM_getFaceArray(DerivedMesh *dm, MFace *face_r)
+static void cdDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
 {
-       memcpy(face_r, CDDM_get_faces(dm), sizeof(*face_r) * dm->getNumFaces(dm));
+       CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
+       memcpy(vert_r, cddm->mvert, sizeof(*vert_r) * dm->numVertData);
 }
 
-static void cdDM_foreachMappedVert(
-                           DerivedMesh *dm,
-                           void (*func)(void *userData, int index, float *co,
-                                        float *no_f, short *no_s),
-                           void *userData)
+static void cdDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
 {
-       int i;
-       int maxVerts = dm->getNumVerts(dm);
-       MVert *mv = CDDM_get_verts(dm);
-       int *index = DM_get_vert_data_layer(dm, LAYERTYPE_ORIGINDEX);
-
-       for(i = 0; i < maxVerts; i++, mv++, index++) {
-               if(*index == ORIGINDEX_NONE) continue;
-
-               func(userData, *index, mv->co, NULL, mv->no);
-       }
+       CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
+       memcpy(edge_r, cddm->medge, sizeof(*edge_r) * dm->numEdgeData);
 }
 
-static void cdDM_foreachMappedEdge(
-                           DerivedMesh *dm,
-                           void (*func)(void *userData, int index,
-                                        float *v0co, float *v1co),
-                           void *userData)
+void cdDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
 {
-       int i;
-       int maxEdges = dm->getNumEdges(dm);
-       MEdge *med = CDDM_get_edges(dm);
-       MVert *mv = CDDM_get_verts(dm);
-       int *index = DM_get_edge_data_layer(dm, LAYERTYPE_ORIGINDEX);
-
-       for(i = 0; i < maxEdges; i++, med++, index++) {
-               if(*index == ORIGINDEX_NONE) continue;
-
-               func(userData, *index, mv[med->v1].co, mv[med->v2].co);
-       }
-}
-
-static void cdDM_foreachMappedFaceCenter(
-                           DerivedMesh *dm,
-                           void (*func)(void *userData, int index,
-                                        float *cent, float *no),
-                           void *userData)
-{
-       int i;
-       int maxFaces = dm->getNumFaces(dm);
-       MFace *mf = CDDM_get_faces(dm);
-       MVert *mv = CDDM_get_verts(dm);
-       int *index = DM_get_face_data_layer(dm, LAYERTYPE_ORIGINDEX);
-
-       for(i = 0; i < maxFaces; i++, mf++, index++) {
-               float cent[3];
-               float no[3];
-
-               if(*index == ORIGINDEX_NONE) continue;
-
-               VECCOPY(cent, mv[mf->v1].co);
-               VecAddf(cent, cent, mv[mf->v2].co);
-               VecAddf(cent, cent, mv[mf->v3].co);
-
-               if (mf->v4) {
-                       CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
-                                      mv[mf->v3].co, mv[mf->v4].co, no);
-                       VecAddf(cent, cent, mv[mf->v4].co);
-                       VecMulf(cent, 0.25f);
-               } else {
-                       CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co,
-                                     mv[mf->v3].co, no);
-                       VecMulf(cent, 0.33333333333f);
-               }
-
-               func(userData, *index, cent, no);
-       }
-}
-
-static DispListMesh *cdDM_convertToDispListMesh(DerivedMesh *dm,
-                                                int allowShared)
-{
-       DispListMesh *dlm = MEM_callocN(sizeof(*dlm),
-                                       "cdDM_convertToDispListMesh dlm");
-
-       dlm->totvert = dm->vertData.numElems;
-       dlm->totedge = dm->edgeData.numElems;
-       dlm->totface = dm->faceData.numElems;
-       dlm->mvert = dm->dupVertArray(dm);
-       dlm->medge = dm->dupEdgeArray(dm);
-       dlm->mface = dm->dupFaceArray(dm);
-
-       dlm->tface = dm->getFaceDataArray(dm, LAYERTYPE_TFACE);
-       if(dlm->tface)
-               dlm->tface = MEM_dupallocN(dlm->tface);
-
-       dlm->mcol = dm->getFaceDataArray(dm, LAYERTYPE_MCOL);
-       if(dlm->mcol)
-               dlm->mcol = MEM_dupallocN(dlm->mcol);
-
-       dlm->nors = NULL;
-       dlm->dontFreeVerts = dlm->dontFreeOther = dlm->dontFreeNors = 0;
-
-       return dlm;
+       CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
+       memcpy(face_r, cddm->mface, sizeof(*face_r) * dm->numFaceData);
 }
 
 static void cdDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
 {
+       CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
        int i;
 
-       for(i = 0; i < dm->vertData.numElems; i++) {
-               DO_MINMAX(CDDM_get_vert(dm, i)->co, min_r, max_r);
+       if (dm->numVertData) {
+               for (i=0; i<dm->numVertData; i++) {
+                       DO_MINMAX(cddm->mvert[i].co, min_r, max_r);
+               }
+       } else {
+               min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
        }
 }
 
 static void cdDM_getVertCo(DerivedMesh *dm, int index, float co_r[3])
 {
-       VECCOPY(co_r, CDDM_get_vert(dm, index)->co);
+       CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
+
+       VECCOPY(co_r, cddm->mvert[index].co);
 }
 
 static void cdDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
 {
-       int i;
        MVert *mv = CDDM_get_verts(dm);
+       int i;
 
-       for(i = 0; i < dm->vertData.numElems; i++, mv++)
+       for(i = 0; i < dm->numVertData; i++, mv++)
                VECCOPY(cos_r[i], mv->co);
 }
 
 static void cdDM_getVertNo(DerivedMesh *dm, int index, float no_r[3])
 {
-       short *no = CDDM_get_vert(dm, index)->no;
+       CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
+       short *no = cddm->mvert[index].no;
 
-       no_r[0] = no[0] / 32767.f;
-       no_r[1] = no[1] / 32767.f;
-       no_r[2] = no[2] / 32767.f;
+       no_r[0] = no[0]/32767.f;
+       no_r[1] = no[1]/32767.f;
+       no_r[2] = no[2]/32767.f;
 }
 
 static void cdDM_drawVerts(DerivedMesh *dm)
 {
+       CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
+       MVert *mv = cddm->mvert;
        int i;
-       MVert *mv = CDDM_get_verts(dm);
 
        glBegin(GL_POINTS);
-       for(i = 0; i < dm->vertData.numElems; i++, mv++)
+       for(i = 0; i < dm->numVertData; i++, mv++)
                glVertex3fv(mv->co);
        glEnd();
 }
 
 static void cdDM_drawUVEdges(DerivedMesh *dm)
 {
+       CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
+       MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
+       MFace *mf = cddm->mface;
        int i;
-       TFace *tf = DM_get_face_data_layer(dm, LAYERTYPE_TFACE);
-       MFace *mf = CDDM_get_faces(dm);
 
        if(tf) {
                glBegin(GL_LINES);
-               for(i = 0; i < dm->faceData.numElems; i++, tf++, mf++) {
+               for(i = 0; i < dm->numFaceData; i++, tf++, mf++) {
                        if(!(tf->flag&TF_HIDE)) {
                                glVertex2fv(tf->uv[0]);
                                glVertex2fv(tf->uv[1]);
@@ -282,12 +209,13 @@ static void cdDM_drawUVEdges(DerivedMesh *dm)
 
 static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
 {
+       CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
+       MVert *mvert = cddm->mvert;
+       MEdge *medge = cddm->medge;
        int i;
-       MEdge *medge = CDDM_get_edges(dm);
-       MVert *mvert = CDDM_get_verts(dm);
                
        glBegin(GL_LINES);
-       for(i = 0; i < dm->edgeData.numElems; i++, medge++) {
+       for(i = 0; i < dm->numEdgeData; i++, medge++) {
                if((medge->flag&ME_EDGEDRAW)
                   && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
                        glVertex3fv(mvert[medge->v1].co);
@@ -299,12 +227,13 @@ static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
 
 static void cdDM_drawLooseEdges(DerivedMesh *dm)
 {
-       MEdge *medge = CDDM_get_edges(dm);
-       MVert *mvert = CDDM_get_verts(dm);
+       CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
+       MVert *mvert = cddm->mvert;
+       MEdge *medge = cddm->medge;
        int i;
 
        glBegin(GL_LINES);
-       for(i = 0; i < dm->edgeData.numElems; i++, medge++) {
+       for(i = 0; i < dm->numEdgeData; i++, medge++) {
                if(medge->flag&ME_LOOSEEDGE) {
                        glVertex3fv(mvert[medge->v1].co);
                        glVertex3fv(mvert[medge->v2].co);
@@ -315,10 +244,11 @@ static void cdDM_drawLooseEdges(DerivedMesh *dm)
 
 static void cdDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
 {
-       int a;
-       int glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1;
-       MFace *mface = CDDM_get_faces(dm);
-       MVert *mvert = CDDM_get_verts(dm);
+       CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
+       MVert *mvert = cddm->mvert;
+       MFace *mface = cddm->mface;
+       float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
+       int a, glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1;
 
 #define PASSVERT(index) {                                              \
        if(shademodel == GL_SMOOTH) {                           \
@@ -329,7 +259,7 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
 }
 
        glBegin(glmode = GL_QUADS);
-       for(a = 0; a < dm->faceData.numElems; a++, mface++) {
+       for(a = 0; a < dm->numFaceData; a++, mface++) {
                int new_glmode, new_matnr, new_shademodel;
 
                new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES;
@@ -347,18 +277,24 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
                } 
                
                if(drawCurrentMat) {
-                       /* TODO make this better (cache facenormals as layer?) */
                        if(shademodel == GL_FLAT) {
-                               float nor[3];
-                               if(mface->v4) {
-                                       CalcNormFloat4(mvert[mface->v1].co, mvert[mface->v2].co,
-                                                      mvert[mface->v3].co, mvert[mface->v4].co,
-                                                      nor);
-                               } else {
-                                       CalcNormFloat(mvert[mface->v1].co, mvert[mface->v2].co,
-                                                     mvert[mface->v3].co, nor);
+                               if (nors) {
+                                       glNormal3fv(nors);
+                                       nors += 3;
+                               }
+                               else {
+                                       /* TODO make this better (cache facenormals as layer?) */
+                                       float nor[3];
+                                       if(mface->v4) {
+                                               CalcNormFloat4(mvert[mface->v1].co, mvert[mface->v2].co,
+                                                                          mvert[mface->v3].co, mvert[mface->v4].co,
+                                                                          nor);
+                                       } else {
+                                               CalcNormFloat(mvert[mface->v1].co, mvert[mface->v2].co,
+                                                                         mvert[mface->v3].co, nor);
+                                       }
+                                       glNormal3fv(nor);
                                }
-                               glNormal3fv(nor);
                        }
 
                        PASSVERT(mface->v1);
@@ -377,10 +313,11 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
 
 static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2)
 {
+       CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
        int a, glmode;
        unsigned char *cp1, *cp2;
-       MFace *mface = CDDM_get_faces(dm);
-       MVert *mvert = CDDM_get_verts(dm);
+       MVert *mvert = cddm->mvert;
+       MFace *mface = cddm->mface;
 
        cp1 = col1;
        if(col2) {
@@ -398,7 +335,7 @@ static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned cha
        
        glShadeModel(GL_SMOOTH);
        glBegin(glmode = GL_QUADS);
-       for(a = 0; a < dm->faceData.numElems; a++, mface++, cp1 += 16) {
+       for(a = 0; a < dm->numFaceData; a++, mface++, cp1 += 16) {
                int new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES;
 
                if(new_glmode != glmode) {
@@ -438,50 +375,59 @@ static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned cha
 }
 
 static void cdDM_drawFacesTex_common(DerivedMesh *dm,
-               int (*drawParams)(TFace *tface, int matnr),
+               int (*drawParams)(MTFace *tface, MCol *mcol, int matnr),
                int (*drawParamsMapped)(void *userData, int index),
                void *userData) 
 {
-       int i;
-       MFace *mf = CDDM_get_faces(dm);
-       TFace *tf = DM_get_face_data_layer(dm, LAYERTYPE_TFACE);
-       MVert *mv = CDDM_get_verts(dm);
-       int *index = DM_get_face_data_layer(dm, LAYERTYPE_ORIGINDEX);
-
-       for(i = 0; i < dm->faceData.numElems; i++, mf++, index++) {
+       CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
+       MVert *mv = cddm->mvert;
+       MFace *mf = cddm->mface;
+       MCol *mcol = dm->getFaceDataArray(dm, CD_MCOL);
+       float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
+       MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
+       int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
+
+       for(i = 0; i < dm->numFaceData; i++, mf++) {
                MVert *mvert;
                int flag;
                unsigned char *cp = NULL;
 
-               if(drawParams)
-                       if(tf) flag = drawParams(&tf[i], mf->mat_nr);
-                       else flag = drawParams(NULL, mf->mat_nr);
-               else if(*index != ORIGINDEX_NONE)
-                       flag = drawParamsMapped(userData, *index);
-               else
-                       flag = 0;
-
-               if(flag == 0) {
-                       continue;
-               } else if(flag == 1) {
-                       if(tf) {
-                               cp = (unsigned char *)tf[i].col;
-                       } else {
-                               cp = DM_get_face_data(dm, i, LAYERTYPE_MCOL);
+               if(drawParams) {
+                       flag = drawParams(tf? &tf[i]: NULL, mcol? &mcol[i*4]: NULL, mf->mat_nr);
+               }
+               else {
+                       if(index) {
+                               orig = *index++;
+                               if(orig == ORIGINDEX_NONE) continue;
+                               flag = drawParamsMapped(userData, orig);
                        }
+                       else
+                               flag = drawParamsMapped(userData, i);
                }
 
-               /* TODO make this better (cache facenormals as layer?) */
+               if(flag == 0)
+                       continue;
+               else if (flag==1 && mcol)
+                       cp= (unsigned char*) &mcol[i*4];
+
                if(!(mf->flag&ME_SMOOTH)) {
-                       float nor[3];
-                       if(mf->v4) {
-                               CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
-                                                          mv[mf->v3].co, mv[mf->v4].co, nor);
-                       } else {
-                               CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co,
-                                                         mv[mf->v3].co, nor);
+                       if (nors) {
+                               glNormal3fv(nors);
+                               nors += 3;
+                       }
+                       else {
+                               /* TODO make this better (cache facenormals as layer?) */
+                               float nor[3];
+                               if(mf->v4) {
+                                       CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
+                                                                  mv[mf->v3].co, mv[mf->v4].co,
+                                                                  nor);
+                               } else {
+                                       CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co,
+                                                                 mv[mf->v3].co, nor);
+                               }
+                               glNormal3fv(nor);
                        }
-                       glNormal3fv(nor);
                }
 
                glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
@@ -514,50 +460,57 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
        }
 }
 
-static void cdDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(TFace *tface, int matnr))
+static void cdDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
 {
        cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
 }
 
 static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors)
 {
-       int i;
-       MFace *mf = CDDM_get_faces(dm);
-       MVert *mv = CDDM_get_verts(dm);
-       int *index = DM_get_face_data_layer(dm, LAYERTYPE_ORIGINDEX);
-       TFace *tf = DM_get_face_data_layer(dm, LAYERTYPE_TFACE);
-       MCol *mc = DM_get_face_data_layer(dm, LAYERTYPE_MCOL);
-
-       for(i = 0; i < dm->faceData.numElems; i++, mf++, index++) {
+       CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
+       MVert *mv = cddm->mvert;
+       MFace *mf = cddm->mface;
+       MCol *mc = DM_get_face_data_layer(dm, CD_MCOL);
+       float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
+       int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
+
+       for(i = 0; i < dm->numFaceData; i++, mf++) {
                int drawSmooth = (mf->flag & ME_SMOOTH);
 
-               if(setDrawOptions && *index == ORIGINDEX_NONE) continue;
+               if(index) {
+                       orig = *index++;
+                       if(setDrawOptions && orig == ORIGINDEX_NONE) continue;
+               }
+               else
+                       orig = i;
 
-               if(!setDrawOptions || setDrawOptions(userData, *index, &drawSmooth)) {
+               if(!setDrawOptions || setDrawOptions(userData, orig, &drawSmooth)) {
                        unsigned char *cp = NULL;
 
-                       if(useColors) {
-                               if(tf) {
-                                       cp = (unsigned char *)tf[i].col;
-                               } else if(mc) {
-                                       cp = (unsigned char *)&mc[i * 4];
-                               }
-                       }
+                       if(useColors && mc)
+                               cp = (unsigned char *)&mc[i * 4];
 
                        glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
                        glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
 
-                       if(!drawSmooth) {
-                               /* TODO make this better (cache facenormals as layer?) */
-                               float nor[3];
-                               if(mf->v4) {
-                                       CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
-                                                                  mv[mf->v3].co, mv[mf->v4].co, nor);
-                               } else {
-                                       CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co,
-                                                                 mv[mf->v3].co, nor);
+                       if (!drawSmooth) {
+                               if (nors) {
+                                       glNormal3fv(nors);
+                                       nors += 3;
+                               }
+                               else {
+                                       /* TODO make this better (cache facenormals as layer?) */
+                                       float nor[3];
+                                       if(mf->v4) {
+                                               CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
+                                                                          mv[mf->v3].co, mv[mf->v4].co,
+                                                                          nor);
+                                       } else {
+                                               CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co,
+                                                                         mv[mf->v3].co, nor);
+                                       }
+                                       glNormal3fv(nor);
                                }
-                               glNormal3fv(nor);
 
                                if(cp) glColor3ub(cp[3], cp[2], cp[1]);
                                glVertex3fv(mv[mf->v1].co);
@@ -598,17 +551,21 @@ static void cdDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void
 
 static void cdDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
 {
-       int i;
-       int *index = DM_get_edge_data_layer(dm, LAYERTYPE_ORIGINDEX);
-       MEdge *edge = CDDM_get_edges(dm);
-       MVert *vert = CDDM_get_verts(dm);
+       CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
+       MVert *vert = cddm->mvert;
+       MEdge *edge = cddm->medge;
+       int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
 
        glBegin(GL_LINES);
-       for(i = 0; i < dm->edgeData.numElems; i++, edge++, index++) {
-
-               if(setDrawOptions && *index == ORIGINDEX_NONE) continue;
+       for(i = 0; i < dm->numEdgeData; i++, edge++) {
+               if(index) {
+                       orig = *index++;
+                       if(setDrawOptions && orig == ORIGINDEX_NONE) continue;
+               }
+               else
+                       orig = i;
 
-               if(!setDrawOptions || setDrawOptions(userData, *index)) {
+               if(!setDrawOptions || setDrawOptions(userData, orig)) {
                        glVertex3fv(vert[edge->v1].co);
                        glVertex3fv(vert[edge->v2].co);
                }
@@ -616,27 +573,108 @@ static void cdDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *us
        glEnd();
 }
 
-static void cdDM_release(DerivedMesh *dm)
+static void cdDM_foreachMappedVert(
+                           DerivedMesh *dm,
+                           void (*func)(void *userData, int index, float *co,
+                                        float *no_f, short *no_s),
+                           void *userData)
 {
-       CustomData_free(&dm->vertData);
-       CustomData_free(&dm->edgeData);
-       CustomData_free(&dm->faceData);
+       MVert *mv = CDDM_get_verts(dm);
+       int i, orig, *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
+
+       for(i = 0; i < dm->numVertData; i++, mv++) {
+               if(index) {
+                       orig = *index++;
+                       if(orig == ORIGINDEX_NONE) continue;
+                       func(userData, orig, mv->co, NULL, mv->no);
+               }
+               else
+                       func(userData, i, mv->co, NULL, mv->no);
+       }
+}
+
+static void cdDM_foreachMappedEdge(
+                           DerivedMesh *dm,
+                           void (*func)(void *userData, int index,
+                                        float *v0co, float *v1co),
+                           void *userData)
+{
+       CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
+       MVert *mv = cddm->mvert;
+       MEdge *med = cddm->medge;
+       int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
+
+       for(i = 0; i < dm->numEdgeData; i++, med++) {
+               if (index) {
+                       orig = *index++;
+                       if(orig == ORIGINDEX_NONE) continue;
+                       func(userData, orig, mv[med->v1].co, mv[med->v2].co);
+               }
+               else
+                       func(userData, i, mv[med->v1].co, mv[med->v2].co);
+       }
+}
+
+static void cdDM_foreachMappedFaceCenter(
+                           DerivedMesh *dm,
+                           void (*func)(void *userData, int index,
+                                        float *cent, float *no),
+                           void *userData)
+{
+       CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
+       MVert *mv = cddm->mvert;
+       MFace *mf = cddm->mface;
+       int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
+
+       for(i = 0; i < dm->numFaceData; i++, mf++) {
+               float cent[3];
+               float no[3];
+
+               if (index) {
+                       orig = *index++;
+                       if(orig == ORIGINDEX_NONE) continue;
+               }
+               else
+                       orig = i;
+
+               VECCOPY(cent, mv[mf->v1].co);
+               VecAddf(cent, cent, mv[mf->v2].co);
+               VecAddf(cent, cent, mv[mf->v3].co);
+
+               if (mf->v4) {
+                       CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
+                                      mv[mf->v3].co, mv[mf->v4].co, no);
+                       VecAddf(cent, cent, mv[mf->v4].co);
+                       VecMulf(cent, 0.25f);
+               } else {
+                       CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co,
+                                     mv[mf->v3].co, no);
+                       VecMulf(cent, 0.33333333333f);
+               }
 
-       MEM_freeN(dm);
+               func(userData, orig, cent, no);
+       }
 }
 
+static void cdDM_release(DerivedMesh *dm)
+{
+       CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
+
+       if (DM_release(dm))
+               MEM_freeN(cddm);
+}
 
 /**************** CDDM interface functions ****************/
-static DerivedMesh *cdDM_create(const char *desc)
+static CDDerivedMesh *cdDM_create(const char *desc)
 {
+       CDDerivedMesh *cddm;
        DerivedMesh *dm;
 
-       dm = MEM_callocN(sizeof(*dm), desc);
+       cddm = MEM_callocN(sizeof(*cddm), desc);
+       dm = &cddm->dm;
 
        dm->getMinMax = cdDM_getMinMax;
 
-       dm->convertToDispListMesh = cdDM_convertToDispListMesh;
-
        dm->getNumVerts = cdDM_getNumVerts;
        dm->getNumFaces = cdDM_getNumFaces;
        dm->getNumEdges = cdDM_getNumEdges;
@@ -644,9 +682,9 @@ static DerivedMesh *cdDM_create(const char *desc)
        dm->getVert = cdDM_getVert;
        dm->getEdge = cdDM_getEdge;
        dm->getFace = cdDM_getFace;
-       dm->getVertArray = cdDM_getVertArray;
-       dm->getEdgeArray = cdDM_getEdgeArray;
-       dm->getFaceArray = cdDM_getFaceArray;
+       dm->copyVertArray = cdDM_copyVertArray;
+       dm->copyEdgeArray = cdDM_copyEdgeArray;
+       dm->copyFaceArray = cdDM_copyFaceArray;
        dm->getVertData = DM_get_vert_data;
        dm->getEdgeData = DM_get_edge_data;
        dm->getFaceData = DM_get_face_data;
@@ -677,64 +715,61 @@ static DerivedMesh *cdDM_create(const char *desc)
 
        dm->release = cdDM_release;
 
-       return dm;
+       return cddm;
 }
 
 DerivedMesh *CDDM_new(int numVerts, int numEdges, int numFaces)
 {
-       DerivedMesh *dm = cdDM_create("CDDM_new dm");
+       CDDerivedMesh *cddm = cdDM_create("CDDM_new dm");
+       DerivedMesh *dm = &cddm->dm;
+
        DM_init(dm, numVerts, numEdges, numFaces);
 
-       CustomData_add_layer(&dm->vertData, LAYERTYPE_MVERT, LAYERFLAG_NOCOPY,
-                            NULL);
-       CustomData_add_layer(&dm->edgeData, LAYERTYPE_MEDGE, LAYERFLAG_NOCOPY,
-                            NULL);
-       CustomData_add_layer(&dm->faceData, LAYERTYPE_MFACE, LAYERFLAG_NOCOPY,
-                            NULL);
+       cddm->mvert = CustomData_add_layer(&dm->vertData, CD_MVERT, 0, 0, numVerts);
+       cddm->medge = CustomData_add_layer(&dm->edgeData, CD_MEDGE, 0, 0, numEdges);
+       cddm->mface = CustomData_add_layer(&dm->faceData, CD_MFACE, 0, 0, numFaces);
 
        return dm;
 }
 
-DerivedMesh *CDDM_from_mesh(Mesh *mesh)
+DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *ob)
 {
-       DerivedMesh *dm = CDDM_new(mesh->totvert, mesh->totedge, mesh->totface);
-       int i;
-
-       if(mesh->msticky)
-               CustomData_add_layer(&dm->vertData, LAYERTYPE_MSTICKY, 0, NULL);
-       if(mesh->dvert)
-               CustomData_add_layer(&dm->vertData, LAYERTYPE_MDEFORMVERT, 0, NULL);
+       CDDerivedMesh *cddm = cdDM_create("CDDM_from_mesh dm");
+       DerivedMesh *dm = &cddm->dm;
+       int i, *index;
 
-       if(mesh->tface)
-               CustomData_add_layer(&dm->faceData, LAYERTYPE_TFACE, 0, NULL);
-       if(mesh->mcol)
-               CustomData_add_layer(&dm->faceData, LAYERTYPE_MCOL, 0, NULL);
+       /* this does a referenced copy, the only new layers being ORIGINDEX */
 
-       for(i = 0; i < mesh->totvert; ++i) {
-               DM_set_vert_data(dm, i, LAYERTYPE_MVERT, &mesh->mvert[i]);
-               if(mesh->msticky)
-                       DM_set_vert_data(dm, i, LAYERTYPE_MSTICKY, &mesh->msticky[i]);
-               if(mesh->dvert)
-                       DM_set_vert_data(dm, i, LAYERTYPE_MDEFORMVERT, &mesh->dvert[i]);
+       DM_init(dm, mesh->totvert, mesh->totedge, mesh->totface);
 
-               DM_set_vert_data(dm, i, LAYERTYPE_ORIGINDEX, &i);
-       }
+       CustomData_merge(&mesh->vdata, &dm->vertData, CD_MASK_MESH, CD_REFERENCE,
+                        mesh->totvert);
+       CustomData_merge(&mesh->edata, &dm->edgeData, CD_MASK_MESH, CD_REFERENCE,
+                        mesh->totedge);
+       CustomData_merge(&mesh->fdata, &dm->faceData, CD_MASK_MESH, CD_REFERENCE,
+                        mesh->totface);
 
-       for(i = 0; i < mesh->totedge; ++i) {
-               DM_set_edge_data(dm, i, LAYERTYPE_MEDGE, &mesh->medge[i]);
+       cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
+       cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
+       cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
 
-               DM_set_edge_data(dm, i, LAYERTYPE_ORIGINDEX, &i);
-       }
+       index = CustomData_get_layer(&dm->vertData, CD_ORIGINDEX);
+       for(i = 0; i < mesh->totvert; ++i, ++index)
+               *index = i;
 
-       for(i = 0; i < mesh->totface; ++i) {
-               DM_set_face_data(dm, i, LAYERTYPE_MFACE, &mesh->mface[i]);
-               if(mesh->tface)
-                       DM_set_face_data(dm, i, LAYERTYPE_TFACE, &mesh->tface[i]);
-               if(mesh->mcol)
-                       DM_set_face_data(dm, i, LAYERTYPE_MCOL, &mesh->mcol[i * 4]);
+       index = CustomData_get_layer(&dm->edgeData, CD_ORIGINDEX);
+       for(i = 0; i < mesh->totedge; ++i, ++index)
+               *index = i;
 
-               DM_set_face_data(dm, i, LAYERTYPE_ORIGINDEX, &i);
-       }
+       index = CustomData_get_layer(&dm->faceData, CD_ORIGINDEX);
+       for(i = 0; i < mesh->totface; ++i, ++index)
+               *index = i;
+       
+       /* works in conjunction with hack during modifier calc, where mcol is
+          temporarily replaced by weight paint colors */
+       if ((G.f & G_WEIGHTPAINT) &&
+               (ob && ob==(G.scene->basact?G.scene->basact->object:NULL)))
+               CustomData_duplicate_referenced_layer(&dm->faceData, CD_MCOL);
 
        return dm;
 }
@@ -744,29 +779,26 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
        DerivedMesh *dm = CDDM_new(BLI_countlist(&em->verts),
                                   BLI_countlist(&em->edges),
                                   BLI_countlist(&em->faces));
+       CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
        EditVert *eve;
        EditEdge *eed;
        EditFace *efa;
-       MVert *mvert = CDDM_get_verts(dm);
-       MEdge *medge = CDDM_get_edges(dm);
-       MFace *mface = CDDM_get_faces(dm);
-       int i, hassticky = 0, hasdvert = 0, hastface = 0, hasmcol = 0;
-       int *index;
+       MVert *mvert = cddm->mvert;
+       MEdge *medge = cddm->medge;
+       MFace *mface = cddm->mface;
+       int i, *index;
+
+       CustomData_merge(&em->vdata, &dm->vertData, CD_MASK_DERIVEDMESH,
+                        CD_CALLOC, dm->numVertData);
+       /* CustomData_merge(&em->edata, &dm->edgeData, CD_MASK_DERIVEDMESH,
+                        CD_CALLOC, dm->numEdgeData); */
+       CustomData_merge(&em->fdata, &dm->faceData, CD_MASK_DERIVEDMESH,
+                        CD_CALLOC, dm->numFaceData);
 
        /* set eve->hash to vert index */
        for(i = 0, eve = em->verts.first; eve; eve = eve->next, ++i)
                eve->tmp.l = i;
 
-       /* check for availability of layers */
-       if(CustomData_has_layer(&em->vdata, LAYERTYPE_MSTICKY))
-               hassticky= CustomData_add_layer(&dm->vertData, LAYERTYPE_MSTICKY, 0, NULL);
-       if(CustomData_has_layer(&em->vdata, LAYERTYPE_MDEFORMVERT))
-               hasdvert= CustomData_add_layer(&dm->vertData, LAYERTYPE_MDEFORMVERT, 0, NULL);
-       if(CustomData_has_layer(&em->vdata, LAYERTYPE_TFACE))
-               hastface= CustomData_add_layer(&dm->vertData, LAYERTYPE_TFACE, 0, NULL);
-       if(CustomData_has_layer(&em->vdata, LAYERTYPE_MCOL))
-               hasmcol= CustomData_add_layer(&dm->vertData, LAYERTYPE_MCOL, 0, NULL);
-
        /* Need to be able to mark loose edges */
        for(eed = em->edges.first; eed; eed = eed->next) {
                eed->f2 = 0;
@@ -778,8 +810,8 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
                if(efa->e4) efa->e4->f2 = 1;
        }
 
-       index = dm->getVertDataArray(dm, LAYERTYPE_ORIGINDEX);
-       for(i = 0, eve = em->verts.first; i < dm->vertData.numElems;
+       index = dm->getVertDataArray(dm, CD_ORIGINDEX);
+       for(i = 0, eve = em->verts.first; i < dm->numVertData;
            i++, eve = eve->next, index++) {
                MVert *mv = &mvert[i];
 
@@ -794,16 +826,11 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
 
                *index = i;
 
-               if(hassticky)
-                       DM_set_vert_data(dm, i, LAYERTYPE_MSTICKY,
-                               CustomData_em_get(&em->vdata, eve->data, LAYERTYPE_MSTICKY));
-               if(hasdvert)
-                       DM_set_vert_data(dm, i, LAYERTYPE_MDEFORMVERT,
-                               CustomData_em_get(&em->vdata, eve->data, LAYERTYPE_MDEFORMVERT));
+               CustomData_from_em_block(&em->vdata, &dm->vertData, eve->data, i);
        }
 
-       index = dm->getEdgeDataArray(dm, LAYERTYPE_ORIGINDEX);
-       for(i = 0, eed = em->edges.first; i < dm->edgeData.numElems;
+       index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
+       for(i = 0, eed = em->edges.first; i < dm->numEdgeData;
            i++, eed = eed->next, index++) {
                MEdge *med = &medge[i];
 
@@ -817,10 +844,12 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
                if(!eed->f2) med->flag |= ME_LOOSEEDGE;
 
                *index = i;
+
+               /* CustomData_from_em_block(&em->edata, &dm->edgeData, eed->data, i); */
        }
 
-       index = dm->getFaceDataArray(dm, LAYERTYPE_ORIGINDEX);
-       for(i = 0, efa = em->faces.first; i < dm->faceData.numElems;
+       index = dm->getFaceDataArray(dm, CD_ORIGINDEX);
+       for(i = 0, efa = em->faces.first; i < dm->numFaceData;
            i++, efa = efa->next, index++) {
                MFace *mf = &mface[i];
 
@@ -830,16 +859,11 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
                mf->v4 = efa->v4 ? efa->v4->tmp.l : 0;
                mf->mat_nr = efa->mat_nr;
                mf->flag = efa->flag;
-               test_index_face(mf, NULL, NULL, efa->v4?4:3);
 
                *index = i;
 
-               if(hastface)
-                       DM_set_face_data(dm, i, LAYERTYPE_TFACE,
-                               CustomData_em_get(&em->fdata, efa->data, LAYERTYPE_TFACE));
-               if(hasmcol)
-                       DM_set_face_data(dm, i, LAYERTYPE_MCOL,
-                               CustomData_em_get(&em->fdata, efa->data, LAYERTYPE_MCOL));
+               CustomData_from_em_block(&em->fdata, &dm->faceData, efa->data, i);
+               test_index_face(mf, &dm->faceData, i, efa->v4?4:3);
        }
 
        return dm;
@@ -847,73 +871,104 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
 
 DerivedMesh *CDDM_copy(DerivedMesh *source)
 {
-       DerivedMesh *dest = CDDM_from_template(source,
-                                              source->vertData.numElems,
-                                              source->edgeData.numElems,
-                                              source->faceData.numElems);
-
-       CustomData_copy_data(&source->vertData, &dest->vertData, 0, 0,
-                            source->vertData.numElems);
-       CustomData_copy_data(&source->edgeData, &dest->edgeData, 0, 0,
-                            source->edgeData.numElems);
-       CustomData_copy_data(&source->faceData, &dest->faceData, 0, 0,
-                            source->faceData.numElems);
-
-       /* copy vert/face/edge data from source */
-       source->getVertArray(source, CDDM_get_verts(dest));
-       source->getEdgeArray(source, CDDM_get_edges(dest));
-       source->getFaceArray(source, CDDM_get_faces(dest));
-
-       return dest;
+       CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm");
+       DerivedMesh *dm = &cddm->dm;
+       int numVerts = source->numVertData;
+       int numEdges = source->numEdgeData;
+       int numFaces = source->numFaceData;
+
+       /* this initializes dm, and copies all non mvert/medge/mface layers */
+       DM_from_template(dm, source, numVerts, numEdges, numFaces);
+
+       CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
+       CustomData_copy_data(&source->edgeData, &dm->edgeData, 0, 0, numEdges);
+       CustomData_copy_data(&source->faceData, &dm->faceData, 0, 0, numFaces);
+
+       /* now add mvert/medge/mface layers */
+       cddm->mvert = source->dupVertArray(source);
+       cddm->medge = source->dupEdgeArray(source);
+       cddm->mface = source->dupFaceArray(source);
+
+       CustomData_add_layer(&dm->vertData, CD_MVERT, 0, cddm->mvert, numVerts);
+       CustomData_add_layer(&dm->edgeData, CD_MEDGE, 0, cddm->medge, numEdges);
+       CustomData_add_layer(&dm->faceData, CD_MFACE, 0, cddm->mface, numFaces);
+
+       return dm;
 }
 
 DerivedMesh *CDDM_from_template(DerivedMesh *source,
                                 int numVerts, int numEdges, int numFaces)
 {
-       DerivedMesh *dest = cdDM_create("CDDM_from_template dest");
-       DM_from_template(dest, source, numVerts, numEdges, numFaces);
-
-       /* if no vert/face/edge layers in custom data, add them */
-       if(!CDDM_get_verts(dest))
-               CustomData_add_layer(&dest->vertData, LAYERTYPE_MVERT,
-                                    LAYERFLAG_NOCOPY, NULL);
-       if(!CDDM_get_edges(dest))
-               CustomData_add_layer(&dest->edgeData, LAYERTYPE_MEDGE,
-                                    LAYERFLAG_NOCOPY, NULL);
-       if(!CDDM_get_faces(dest))
-               CustomData_add_layer(&dest->faceData, LAYERTYPE_MFACE,
-                                    LAYERFLAG_NOCOPY, NULL);
-
-       return dest;
+       CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest");
+       DerivedMesh *dm = &cddm->dm;
+
+       /* this does a copy of all non mvert/medge/mface layers */
+       DM_from_template(dm, source, numVerts, numEdges, numFaces);
+
+       /* now add mvert/medge/mface layers */
+       cddm->mvert = CustomData_add_layer(&dm->vertData, CD_MVERT, 0, 0, numVerts);
+       cddm->medge = CustomData_add_layer(&dm->edgeData, CD_MEDGE, 0, 0, numEdges);
+       cddm->mface = CustomData_add_layer(&dm->faceData, CD_MFACE, 0, 0, numFaces);
+
+       return dm;
 }
 
 void CDDM_apply_vert_coords(DerivedMesh *dm, float (*vertCoords)[3])
 {
+       CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
+       MVert *vert;
        int i;
-       MVert *vert = CDDM_get_verts(dm);
 
-       for(i = 0; i < dm->vertData.numElems; ++i, ++vert)
+       /* this will just return the pointer if it wasn't a referenced layer */
+       vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
+       cddm->mvert = vert;
+
+       for(i = 0; i < dm->numVertData; ++i, ++vert)
                VECCOPY(vert->co, vertCoords[i]);
 }
 
+void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3])
+{
+       CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
+       MVert *vert;
+       int i;
+
+       /* this will just return the pointer if it wasn't a referenced layer */
+       vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
+       cddm->mvert = vert;
+
+       for(i = 0; i < dm->numVertData; ++i, ++vert)
+               VECCOPY(vert->no, vertNormals[i]);
+}
+
 /* adapted from mesh_calc_normals */
 void CDDM_calc_normals(DerivedMesh *dm)
 {
+       CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
        float (*temp_nors)[3];
        float (*face_nors)[3];
        int i;
-       int numVerts = dm->getNumVerts(dm);
-       int numFaces = dm->getNumFaces(dm);
+       int numVerts = dm->numVertData;
+       int numFaces = dm->numFaceData;
        MFace *mf;
-       MVert *mv = CDDM_get_verts(dm);
+       MVert *mv;
 
-       if(!mv) return;
+       if(numVerts == 0) return;
 
        temp_nors = MEM_callocN(numVerts * sizeof(*temp_nors),
                                "CDDM_calc_normals temp_nors");
-       face_nors = MEM_mallocN(numFaces * sizeof(*face_nors),
-                               "CDDM_calc_normals face_nors");
 
+       /* we don't want to overwrite any referenced layers */
+       mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
+       cddm->mvert = mv;
+
+       /* make a face normal layer if not present */
+       face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
+       if(!face_nors)
+               face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, 0, NULL,
+                                                dm->numFaceData);
+
+       /* calculate face normals and add to vertex normals */
        mf = CDDM_get_faces(dm);
        for(i = 0; i < numFaces; i++, mf++) {
                float *f_no = face_nors[i];
@@ -932,6 +987,7 @@ void CDDM_calc_normals(DerivedMesh *dm)
                        VecAddf(temp_nors[mf->v4], temp_nors[mf->v4], f_no);
        }
 
+       /* normalize vertex normals and assign */
        for(i = 0; i < numVerts; i++, mv++) {
                float *no = temp_nors[i];
                
@@ -946,20 +1002,17 @@ void CDDM_calc_normals(DerivedMesh *dm)
        }
        
        MEM_freeN(temp_nors);
-
-       /* TODO maybe cache face normals here? */
-       MEM_freeN(face_nors);
 }
 
 void CDDM_calc_edges(DerivedMesh *dm)
 {
+       CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
        CustomData edgeData;
-       EdgeHash *eh = BLI_edgehash_new();
        EdgeHashIterator *ehi;
-       int i;
-       int maxFaces = dm->getNumFaces(dm);
-       MFace *mf = CDDM_get_faces(dm);
+       MFace *mf = cddm->mface;
        MEdge *med;
+       EdgeHash *eh = BLI_edgehash_new();
+       int i, numEdges, maxFaces = dm->numFaceData;
 
        for (i = 0; i < maxFaces; i++, mf++) {
                if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
@@ -978,14 +1031,14 @@ void CDDM_calc_edges(DerivedMesh *dm)
                }
        }
 
-       CustomData_from_template(&dm->edgeData, &edgeData, 0, BLI_edgehash_size(eh));
-
-       if(!CustomData_get_layer(&edgeData, LAYERTYPE_MEDGE))
-               CustomData_add_layer(&edgeData, LAYERTYPE_MEDGE,
-                                    LAYERFLAG_NOCOPY, NULL);
+       numEdges = BLI_edgehash_size(eh);
 
+       /* write new edges into a temporary CustomData */
+       memset(&edgeData, 0, sizeof(edgeData));
+       CustomData_add_layer(&edgeData, CD_MEDGE, 0, NULL, numEdges);
+       
        ehi = BLI_edgehashIterator_new(eh);
-       med = CustomData_get_layer(&edgeData, LAYERTYPE_MEDGE);
+       med = CustomData_get_layer(&edgeData, CD_MEDGE);
        for(i = 0; !BLI_edgehashIterator_isDone(ehi);
            BLI_edgehashIterator_step(ehi), ++i, ++med) {
                BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
@@ -994,54 +1047,67 @@ void CDDM_calc_edges(DerivedMesh *dm)
        }
        BLI_edgehashIterator_free(ehi);
 
-       CustomData_free(&dm->edgeData);
+       /* free old CustomData and assign new one */
+       CustomData_free(&dm->edgeData, dm->numVertData);
        dm->edgeData = edgeData;
+       dm->numEdgeData = numEdges;
+
+       cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
 
        BLI_edgehash_free(eh, NULL);
 }
 
-void CDDM_set_num_verts(DerivedMesh *dm, int numVerts)
+void CDDM_lower_num_verts(DerivedMesh *dm, int numVerts)
 {
-       CustomData_set_num_elems(&dm->vertData, numVerts);
+       if (numVerts < dm->numVertData)
+               CustomData_free_elem(&dm->vertData, numVerts, dm->numVertData - numVerts);
+
+       dm->numVertData = numVerts;
 }
 
-void CDDM_set_num_edges(DerivedMesh *dm, int numEdges)
+void CDDM_lower_num_edges(DerivedMesh *dm, int numEdges)
 {
-       CustomData_set_num_elems(&dm->edgeData, numEdges);
+       if (numEdges < dm->numEdgeData)
+               CustomData_free_elem(&dm->edgeData, numEdges, dm->numEdgeData - numEdges);
+
+       dm->numEdgeData = numEdges;
 }
 
-void CDDM_set_num_faces(DerivedMesh *dm, int numFaces)
+void CDDM_lower_num_faces(DerivedMesh *dm, int numFaces)
 {
-       CustomData_set_num_elems(&dm->faceData, numFaces);
+       if (numFaces < dm->numFaceData)
+               CustomData_free_elem(&dm->faceData, numFaces, dm->numFaceData - numFaces);
+
+       dm->numFaceData = numFaces;
 }
 
 MVert *CDDM_get_vert(DerivedMesh *dm, int index)
 {
-       return CustomData_get(&dm->vertData, index, LAYERTYPE_MVERT);
+       return &((CDDerivedMesh*)dm)->mvert[index];
 }
 
 MEdge *CDDM_get_edge(DerivedMesh *dm, int index)
 {
-       return CustomData_get(&dm->edgeData, index, LAYERTYPE_MEDGE);
+       return &((CDDerivedMesh*)dm)->medge[index];
 }
 
 MFace *CDDM_get_face(DerivedMesh *dm, int index)
 {
-       return CustomData_get(&dm->faceData, index, LAYERTYPE_MFACE);
+       return &((CDDerivedMesh*)dm)->mface[index];
 }
 
 MVert *CDDM_get_verts(DerivedMesh *dm)
 {
-       return CustomData_get_layer(&dm->vertData, LAYERTYPE_MVERT);
+       return ((CDDerivedMesh*)dm)->mvert;
 }
 
 MEdge *CDDM_get_edges(DerivedMesh *dm)
 {
-       return CustomData_get_layer(&dm->edgeData, LAYERTYPE_MEDGE);
+       return ((CDDerivedMesh*)dm)->medge;
 }
 
 MFace *CDDM_get_faces(DerivedMesh *dm)
 {
-       return CustomData_get_layer(&dm->faceData, LAYERTYPE_MFACE);
+       return ((CDDerivedMesh*)dm)->mface;
 }
 
index c626c79bdcc775b542e3eade9397e8ff767b3bc0..21b77f671e4a8020804d94e6ddda4d839464ac40 100644 (file)
@@ -37,7 +37,7 @@
 #include "BLI_linklist.h"
 
 #include "DNA_customdata_types.h"
-#include "DNA_mesh_types.h"
+#include "DNA_listbase.h"
 #include "DNA_meshdata_types.h"
 
 #include "MEM_guardedalloc.h"
@@ -49,7 +49,9 @@
 
 /********************* Layer type information **********************/
 typedef struct LayerTypeInfo {
-       int size; /* the memory size of one element of this layer's data */
+       int size;          /* the memory size of one element of this layer's data */
+       char *structname;  /* name of the struct used, for file writing */
+       int structnum;     /* number of structs per element, for file writing */
 
        /* a function to copy count elements of this layer's data
         * (deep copy if appropriate)
@@ -78,9 +80,12 @@ typedef struct LayerTypeInfo {
        void (*interp)(void **sources, float *weights, float *sub_weights,
                       int count, void *dest);
 
+    /* a function to swap the data in corners of the element */
+       void (*swap)(void *data, int *corner_indices);
+
     /* a function to set a layer's data to default values. if NULL, the
           default is assumed to be all zeros */
-       void (*set_default)(void *data);
+       void (*set_default)(void *data, int count);
 } LayerTypeInfo;
 
 static void layerCopy_mdeformvert(const void *source, void *dest,
@@ -110,6 +115,7 @@ static void layerFree_mdeformvert(void *data, int count, int size)
                if(dvert->dw) {
                        MEM_freeN(dvert->dw);
                        dvert->dw = NULL;
+                       dvert->totweight = 0;
                }
        }
 }
@@ -176,10 +182,33 @@ static void layerInterp_mdeformvert(void **sources, float *weights,
        BLI_linklist_free(dest_dw, linklist_free_simple);
 }
 
+
+static void layerInterp_msticky(void **sources, float *weights,
+                                float *sub_weights, int count, void *dest)
+{
+       float co[2], w;
+       MSticky *mst;
+       int i;
+
+       co[0] = co[1] = 0.0f;
+       for(i = 0; i < count; i++) {
+               w = weights ? weights[i] : 1.0f;
+               mst = (MSticky*)sources[i];
+
+               co[0] += w*mst->co[0];
+               co[1] += w*mst->co[1];
+       }
+
+       mst = (MSticky*)dest;
+       mst->co[0] = co[0];
+       mst->co[1] = co[1];
+}
+
+
 static void layerCopy_tface(const void *source, void *dest, int count, int size)
 {
-       const TFace *source_tf = (const TFace*)source;
-       TFace *dest_tf = (TFace*)dest;
+       const MTFace *source_tf = (const MTFace*)source;
+       MTFace *dest_tf = (MTFace*)dest;
        int i;
 
        for(i = 0; i < count; ++i) {
@@ -191,70 +220,66 @@ static void layerCopy_tface(const void *source, void *dest, int count, int size)
 static void layerInterp_tface(void **sources, float *weights,
                               float *sub_weights, int count, void *dest)
 {
-       TFace *tf = dest;
+       MTFace *tf = dest;
        int i, j, k;
        float uv[4][2];
-       float col[4][4];
        float *sub_weight;
 
        if(count <= 0) return;
 
        memset(uv, 0, sizeof(uv));
-       memset(col, 0, sizeof(col));
 
        sub_weight = sub_weights;
        for(i = 0; i < count; ++i) {
                float weight = weights ? weights[i] : 1;
-               TFace *src = sources[i];
+               MTFace *src = sources[i];
 
                for(j = 0; j < 4; ++j) {
                        if(sub_weights) {
                                for(k = 0; k < 4; ++k, ++sub_weight) {
                                        float w = (*sub_weight) * weight;
-                                       char *tmp_col = (char *)&src->col[k];
                                        float *tmp_uv = src->uv[k];
 
                                        uv[j][0] += tmp_uv[0] * w;
                                        uv[j][1] += tmp_uv[1] * w;
-
-                                       col[j][0] += tmp_col[0] * w;
-                                       col[j][1] += tmp_col[1] * w;
-                                       col[j][2] += tmp_col[2] * w;
-                                       col[j][3] += tmp_col[3] * w;
                                }
                        } else {
-                               char *tmp_col = (char *)&src->col[j];
                                uv[j][0] += src->uv[j][0] * weight;
                                uv[j][1] += src->uv[j][1] * weight;
-
-                               col[j][0] += tmp_col[0] * weight;
-                               col[j][1] += tmp_col[1] * weight;
-                               col[j][2] += tmp_col[2] * weight;
-                               col[j][3] += tmp_col[3] * weight;
                        }
                }
        }
 
-       *tf = *(TFace *)sources[0];
+       *tf = *(MTFace *)sources[0];
        for(j = 0; j < 4; ++j) {
-               char *tmp_col = (char *)&tf->col[j];
-
                tf->uv[j][0] = uv[j][0];
                tf->uv[j][1] = uv[j][1];
+       }
+}
+
+static void layerSwap_tface(void *data, int *corner_indices)
+{
+       MTFace *tf = data;
+       float uv[4][2];
+       int j;
 
-               tmp_col[0] = (int)col[j][0];
-               tmp_col[1] = (int)col[j][1];
-               tmp_col[2] = (int)col[j][2];
-               tmp_col[3] = (int)col[j][3];
+       for(j = 0; j < 4; ++j) {
+               uv[j][0] = tf->uv[corner_indices[j]][0];
+               uv[j][1] = tf->uv[corner_indices[j]][1];
        }
+
+       memcpy(tf->uv, uv, sizeof(tf->uv));
 }
 
-static void layerDefault_tface(void *data)
+static void layerDefault_tface(void *data, int count)
 {
-       static TFace default_tf = {NULL, {{0, 1}, {0, 0}, {1, 0}, {1, 1}},
-                                  {~0, ~0, ~0, ~0}, TF_SELECT, 0, TF_DYNAMIC, 0, 0};
+       static MTFace default_tf = {{{0, 1}, {0, 0}, {1, 0}, {1, 1}}, NULL,
+                                  TF_SELECT, 0, TF_DYNAMIC, 0, 0};
+       MTFace *tf = (MTFace*)data;
+       int i;
 
-       *((TFace*)data) = default_tf;
+       for(i = 0; i < count; i++)
+               tf[i] = default_tf;
 }
 
 static void layerInterp_mcol(void **sources, float *weights,
@@ -305,111 +330,164 @@ static void layerInterp_mcol(void **sources, float *weights,
        }
 }
 
-static void layerDefault_mcol(void *data)
+static void layerSwap_mcol(void *data, int *corner_indices)
+{
+       MCol *mcol = data;
+       MCol col[4];
+       int j;
+
+       for(j = 0; j < 4; ++j)
+               col[j] = mcol[corner_indices[j]];
+
+       memcpy(mcol, col, sizeof(col));
+}
+
+static void layerDefault_mcol(void *data, int count)
 {
        static MCol default_mcol = {255, 255, 255, 255};
        MCol *mcol = (MCol*)data;
+       int i;
+
+       for(i = 0; i < 4*count; i++)
+               mcol[i] = default_mcol;
+}
 
-       mcol[0]= default_mcol;
-       mcol[1]= default_mcol;
-       mcol[2]= default_mcol;
-       mcol[3]= default_mcol;
-}
-
-const LayerTypeInfo LAYERTYPEINFO[LAYERTYPE_NUMTYPES] = {
-       {sizeof(MVert), NULL, NULL, NULL, NULL},
-       {sizeof(MSticky), NULL, NULL, NULL, NULL},
-       {sizeof(MDeformVert), layerCopy_mdeformvert,
-        layerFree_mdeformvert, layerInterp_mdeformvert, NULL},
-       {sizeof(MEdge), NULL, NULL, NULL, NULL},
-       {sizeof(MFace), NULL, NULL, NULL, NULL},
-       {sizeof(TFace), layerCopy_tface, NULL, layerInterp_tface,
-        layerDefault_tface},
+const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
+       {sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL},
+       {sizeof(MSticky), "MSticky", 1, NULL, NULL, layerInterp_msticky, NULL, NULL},
+       {sizeof(MDeformVert), "MDeformVert", 1, layerCopy_mdeformvert,
+        layerFree_mdeformvert, layerInterp_mdeformvert, NULL, NULL},
+       {sizeof(MEdge), "MEdge", 1, NULL, NULL, NULL, NULL, NULL},
+       {sizeof(MFace), "MFace", 1, NULL, NULL, NULL, NULL, NULL},
+       {sizeof(MTFace), "MTFace", 1, layerCopy_tface, NULL, layerInterp_tface,
+        layerSwap_tface, layerDefault_tface},
        /* 4 MCol structs per face */
-       {sizeof(MCol) * 4, NULL, NULL, layerInterp_mcol, layerDefault_mcol},
-       {sizeof(int), NULL, NULL, NULL, NULL},
+       {sizeof(MCol)*4, "MCol", 4, NULL, NULL, layerInterp_mcol, layerSwap_mcol,
+        layerDefault_mcol},
+       {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL},
        /* 3 floats per normal vector */
-       {sizeof(float) * 3, NULL, NULL, NULL, NULL},
-       {sizeof(int), NULL, NULL, NULL, NULL},
+       {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL},
+       {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL},
 };
 
+const char *LAYERTYPENAMES[CD_NUMTYPES] = {
+       "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace",
+       "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags"};
+
+CustomDataMask CD_MASK_MESH[CD_NUMTYPES] = {
+       1, 1, 1, 1, 1, 1, 1, 0, 0, 0};
+CustomDataMask CD_MASK_EDITMESH[CD_NUMTYPES] = {
+       0, 1, 1, 0, 0, 1, 1, 0, 0, 0};
+CustomDataMask CD_MASK_DERIVEDMESH[CD_NUMTYPES] = {
+       0, 1, 1, 0, 0, 1, 1, 1, 0, 0};
+
 static const LayerTypeInfo *layerType_getInfo(int type)
 {
-       if(type < 0 || type >= LAYERTYPE_NUMTYPES) return NULL;
+       if(type < 0 || type >= CD_NUMTYPES) return NULL;
 
        return &LAYERTYPEINFO[type];
 }
 
-/********************* CustomData functions *********************/
-void CustomData_init(CustomData *data,
-                     int maxLayers, int maxElems, int subElems)
+static const char *layerType_getName(int type)
 {
-       data->layers = MEM_callocN(maxLayers * sizeof(*data->layers),
-                                   "CustomData->layers");
-       data->numLayers = 0;
-       data->maxLayers = maxLayers;
-       data->numElems = maxElems;
-       data->maxElems = maxElems;
-       data->subElems = subElems;
+       if(type < 0 || type >= CD_NUMTYPES) return NULL;
+
+       return LAYERTYPENAMES[type];
 }
 
+/********************* CustomData functions *********************/
 static void CustomData_update_offsets(CustomData *data)
 {
        const LayerTypeInfo *typeInfo;
        int i, offset = 0;
 
-       for(i = 0; i < data->numLayers; ++i) {
+       for(i = 0; i < data->totlayer; ++i) {
                typeInfo = layerType_getInfo(data->layers[i].type);
 
                data->layers[i].offset = offset;
                offset += typeInfo->size;
        }
 
-       data->totSize = offset;
+       data->totsize = offset;
 }
 
-void CustomData_from_template(const CustomData *source, CustomData *dest,
-                              int flag, int maxElems)
+void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
+                      CustomDataMask *mask, int alloctype, int totelem)
 {
-       int i, layerflag;
+       const LayerTypeInfo *typeInfo;
+       CustomDataLayer *layer;
+       int i, flag, type;
+       void *data;
 
-       CustomData_init(dest, source->maxLayers, maxElems, source->subElems);
+       for(i = 0; i < source->totlayer; ++i) {
+               layer = &source->layers[i];
+               typeInfo = layerType_getInfo(layer->type);
 
-       for(i = 0; i < source->numLayers; ++i) {
-               if(source->layers[i].flag & LAYERFLAG_NOCOPY) continue;
+               if(layer->flag & CD_FLAG_NOCOPY) continue;
+               else if(mask && !mask[layer->type]) continue;
+               else if(CustomData_has_layer(dest, layer->type)) continue;
 
-               layerflag = (source->layers[i].flag & ~LAYERFLAG_NOFREE) | flag;
-               CustomData_add_layer(dest, source->layers[i].type, layerflag, NULL);
+               type = layer->type;
+               flag = layer->flag & ~CD_FLAG_NOFREE;
+               data = layer->data;
+
+               if (alloctype == CD_CALLOC) {
+                       CustomData_add_layer(dest, type, flag, NULL, totelem);
+               }
+               else if (alloctype == CD_REFERENCE) {
+                       CustomData_add_layer(dest, type, flag|CD_FLAG_NOFREE, data, totelem);
+               }
+               else if (alloctype == CD_DUPLICATE) {
+                       CustomData_add_layer(dest, type, flag, MEM_dupallocN(data), totelem);
+               }
+               else if (alloctype == CD_DEFAULT) {
+                       data = CustomData_add_layer(dest, type, flag, NULL, totelem);
+                       if(typeInfo->set_default)
+                               typeInfo->set_default((char*)data, totelem);
+               }
        }
 
        CustomData_update_offsets(dest);
+
 }
 
-void CustomData_free(CustomData *data)
+void CustomData_copy(const struct CustomData *source, struct CustomData *dest,
+                     CustomDataMask *mask, int alloctype, int totelem)
+{
+       memset(dest, 0, sizeof(*dest));
+
+       CustomData_merge(source, dest, mask, alloctype, totelem);
+}
+
+static void CustomData_free_layer__internal(CustomDataLayer *layer, int totelem)
 {
-       int i;
        const LayerTypeInfo *typeInfo;
 
-       for(i = 0; i < data->numLayers; ++i) {
-               if(!(data->layers[i].flag & LAYERFLAG_NOFREE)) {
-                       typeInfo = layerType_getInfo(data->layers[i].type);
-                       if(typeInfo->free)
-                               typeInfo->free(data->layers[i].data, data->numElems,
-                                              typeInfo->size);
+       if(!(layer->flag & CD_FLAG_NOFREE) && layer->data) {
+               typeInfo = layerType_getInfo(layer->type);
 
-                       if(data->layers[i].data)
-                               MEM_freeN(data->layers[i].data);
-               }
+               if(typeInfo->free)
+                       typeInfo->free(layer->data, totelem, typeInfo->size);
+
+               if(layer->data)
+                       MEM_freeN(layer->data);
        }
+}
 
-       data->numLayers = 0;
+void CustomData_free(CustomData *data, int totelem)
+{
+       int i;
+
+       for(i = 0; i < data->totlayer; ++i)
+               CustomData_free_layer__internal(&data->layers[i], totelem);
 
-       if(data->layers) {
+       if(data->layers)
                MEM_freeN(data->layers);
-               data->layers = NULL;
-       }
+       
+       memset(data, 0, sizeof(*data));
 }
 
+
 /* gets index of first layer matching type after start_index
  * if start_index < 0, starts searching at 0
  * returns -1 if there is no layer of type
@@ -421,7 +499,7 @@ static int CustomData_find_next(const CustomData *data, int type,
 
        if(i < 0) i = 0;
 
-       for(; i < data->numLayers; ++i)
+       for(; i < data->totlayer; ++i)
                if(data->layers[i].type == type) return i;
 
        return -1;
@@ -429,26 +507,28 @@ static int CustomData_find_next(const CustomData *data, int type,
 
 static int customData_resize(CustomData *data, int amount)
 {
-       CustomDataLayer *tmp = MEM_callocN(sizeof(*tmp)*(data->maxLayers + amount),
+       CustomDataLayer *tmp = MEM_callocN(sizeof(*tmp)*(data->maxlayer + amount),
                                        "CustomData->layers");
        if(!tmp) return 0;
 
-       data->maxLayers += amount;
-       memcpy(tmp, data->layers, sizeof(*tmp) * data->numLayers);
-
-       MEM_freeN(data->layers);
+       data->maxlayer += amount;
+       if (data->layers) {
+               memcpy(tmp, data->layers, sizeof(*tmp) * data->totlayer);
+               MEM_freeN(data->layers);
+       }
        data->layers = tmp;
 
        return 1;
 }
 
-static int customData_add_layer__internal(CustomData *data, int type,
-                                          int flag, void *layer)
+static int customData_add_layer__internal(CustomData *data, int type, int flag,
+                                          void *layer)
 {
-       int index = data->numLayers;
+       int index = data->totlayer;
 
-       if(index >= data->maxLayers)
-               if(!customData_resize(data, CUSTOMDATA_GROW)) return 0;
+       if(index >= data->maxlayer)
+               if(!customData_resize(data, CUSTOMDATA_GROW))
+                       return 0;
        
        /* keep layers ordered by type */
        for( ; index > 0 && data->layers[index - 1].type > type; --index)
@@ -458,42 +538,46 @@ static int customData_add_layer__internal(CustomData *data, int type,
        data->layers[index].flag = flag;
        data->layers[index].data = layer;
 
-       data->numLayers++;
+       data->totlayer++;
 
        CustomData_update_offsets(data);
 
        return 1;
 }
 
-int CustomData_add_layer(CustomData *data, int type, int flag, void *layer)
+void *CustomData_add_layer(CustomData *data, int type, int flag,
+                           void *layerdata, int totelem)
 {
-       int size = layerType_getInfo(type)->size * data->numElems;
-       void *tmp_layer = layer;
+       int size = layerType_getInfo(type)->size * totelem;
+       void *tmpdata = layerdata;
 
-       if(!layer) tmp_layer = MEM_callocN(size, "CustomDataLayer.data");
+       if(!tmpdata)
+               tmpdata = MEM_callocN(size, layerType_getName(type));
+       if(!tmpdata)
+               return NULL;
 
-       if(!tmp_layer) return 0;
-
-       if(customData_add_layer__internal(data, type, flag, tmp_layer))
-               return 1;
-       else {
-               MEM_freeN(tmp_layer);
-               return 0;
+       if(!customData_add_layer__internal(data, type, flag, tmpdata)) {
+               MEM_freeN(tmpdata);
+               return NULL;
        }
+       
+       return tmpdata;
 }
 
-int CustomData_free_layer(CustomData *data, int type)
+int CustomData_free_layer(CustomData *data, int type, int totelem)
 {
        int index = CustomData_find_next(data, type, -1);
 
        if (index < 0) return 0;
 
-       for(++index; index < data->numLayers; ++index)
+       CustomData_free_layer__internal(&data->layers[index], totelem);
+
+       for(++index; index < data->totlayer; ++index)
                data->layers[index - 1] = data->layers[index];
 
-       data->numLayers--;
+       data->totlayer--;
 
-       if(data->numLayers <= data->maxLayers-CUSTOMDATA_GROW)
+       if(data->totlayer <= data->maxlayer-CUSTOMDATA_GROW)
                customData_resize(data, -CUSTOMDATA_GROW);
 
        CustomData_update_offsets(data);
@@ -501,18 +585,62 @@ int CustomData_free_layer(CustomData *data, int type)
        return 1;
 }
 
-int CustomData_has_layer(const struct CustomData *data, int type)
+int CustomData_has_layer(const CustomData *data, int type)
 {
        return (CustomData_find_next(data, type, -1) != -1);
 }
 
+void *CustomData_duplicate_referenced_layer(struct CustomData *data, int type)
+{
+       CustomDataLayer *layer;
+       int layer_index;
+
+       /* get the layer index of the first layer of type */
+       layer_index = CustomData_find_next(data, type, -1);
+       if(layer_index < 0) return NULL;
+
+       layer = &data->layers[layer_index];
+
+       if (layer->flag & CD_FLAG_NOFREE) {
+               layer->data = MEM_dupallocN(layer->data);
+               layer->flag &= ~CD_FLAG_NOFREE;
+       }
+
+       return layer->data;
+}
+
+void CustomData_free_temporary(CustomData *data, int totelem)
+{
+       CustomDataLayer *layer;
+       int i, j;
+
+       for(i = 0, j = 0; i < data->totlayer; ++i) {
+               layer = &data->layers[i];
+
+               if (i != j)
+                       data->layers[j] = data->layers[i];
+
+               if ((layer->flag & CD_FLAG_TEMPORARY) == CD_FLAG_TEMPORARY)
+                       CustomData_free_layer__internal(layer, totelem);
+               else
+                       j++;
+       }
+
+       data->totlayer = j;
+
+       if(data->totlayer <= data->maxlayer-CUSTOMDATA_GROW)
+               customData_resize(data, -CUSTOMDATA_GROW);
+
+       CustomData_update_offsets(data);
+}
+
 int CustomData_compat(const CustomData *data1, const CustomData *data2)
 {
        int i;
 
-       if(data1->numLayers != data2->numLayers) return 0;
+       if(data1->totlayer != data2->totlayer) return 0;
 
-       for(i = 0; i < data1->numLayers; ++i) {
+       for(i = 0; i < data1->totlayer; ++i) {
                if(data1->layers[i].type != data2->layers[i].type) return 0;
                if(data1->layers[i].flag != data2->layers[i].flag) return 0;
        }
@@ -520,34 +648,28 @@ int CustomData_compat(const CustomData *data1, const CustomData *data2)
        return 1;
 }
 
-int CustomData_copy_data(const CustomData *source, CustomData *dest,
-                         int source_index, int dest_index, int count)
+void CustomData_copy_data(const CustomData *source, CustomData *dest,
+                          int source_index, int dest_index, int count)
 {
        const LayerTypeInfo *type_info;
        int src_i, dest_i;
        int src_offset;
        int dest_offset;
 
-       if(count < 0) return 0;
-       if(source_index < 0 || (source_index + count) > source->numElems)
-               return 0;
-       if(dest_index < 0 || (dest_index + count) > dest->numElems)
-               return 0;
-
        /* copies a layer at a time */
        dest_i = 0;
-       for(src_i = 0; src_i < source->numLayers; ++src_i) {
-               if(source->layers[src_i].flag & LAYERFLAG_NOCOPY) continue;
+       for(src_i = 0; src_i < source->totlayer; ++src_i) {
+               if(source->layers[src_i].flag & CD_FLAG_NOCOPY) continue;
 
                /* find the first dest layer with type >= the source type
                 * (this should work because layers are ordered by type)
                 */
-               while(dest_i < dest->numLayers
+               while(dest_i < dest->totlayer
                      && dest->layers[dest_i].type < source->layers[src_i].type)
                        ++dest_i;
 
                /* if there are no more dest layers, we're done */
-               if(dest_i >= dest->numLayers) return 1;
+               if(dest_i >= dest->totlayer) return;
 
                /* if we found a matching layer, copy the data */
                if(dest->layers[dest_i].type == source->layers[src_i].type) {
@@ -575,19 +697,15 @@ int CustomData_copy_data(const CustomData *source, CustomData *dest,
                        ++dest_i;
                }
        }
-
-       return 1;
 }
 
-int CustomData_free_elem(CustomData *data, int index, int count)
+void CustomData_free_elem(CustomData *data, int index, int count)
 {
        int i;
        const LayerTypeInfo *typeInfo;
 
-       if(index < 0 || count <= 0 || index + count > data->numElems) return 0;
-
-       for(i = 0; i < data->numLayers; ++i) {
-               if(!(data->layers[i].flag & LAYERFLAG_NOFREE)) {
+       for(i = 0; i < data->totlayer; ++i) {
+               if(!(data->layers[i].flag & CD_FLAG_NOFREE)) {
                        typeInfo = layerType_getInfo(data->layers[i].type);
 
                        if(typeInfo->free) {
@@ -598,15 +716,13 @@ int CustomData_free_elem(CustomData *data, int index, int count)
                        }
                }
        }
-
-       return 1;
 }
 
 #define SOURCE_BUF_SIZE 100
 
-int CustomData_interp(const CustomData *source, CustomData *dest,
-                      int *src_indices, float *weights, float *sub_weights,
-                      int count, int dest_index)
+void CustomData_interp(const CustomData *source, CustomData *dest,
+                       int *src_indices, float *weights, float *sub_weights,
+                       int count, int dest_index)
 {
        int src_i, dest_i;
        int dest_offset;
@@ -614,9 +730,6 @@ int CustomData_interp(const CustomData *source, CustomData *dest,
        void *source_buf[SOURCE_BUF_SIZE];
        void **sources = source_buf;
 
-       if(count <= 0) return 0;
-       if(dest_index < 0 || dest_index >= dest->numElems) return 0;
-
        /* slow fallback in case we're interpolating a ridiculous number of
         * elements
         */
@@ -625,7 +738,7 @@ int CustomData_interp(const CustomData *source, CustomData *dest,
                                      "CustomData_interp sources");
 
        /* interpolates a layer at a time */
-       for(src_i = 0; src_i < source->numLayers; ++src_i) {
+       for(src_i = 0; src_i < source->totlayer; ++src_i) {
                CustomDataLayer *source_layer = &source->layers[src_i];
                const LayerTypeInfo *type_info =
                                        layerType_getInfo(source_layer->type);
@@ -647,7 +760,22 @@ int CustomData_interp(const CustomData *source, CustomData *dest,
        }
 
        if(count > SOURCE_BUF_SIZE) MEM_freeN(sources);
-       return 1;
+}
+
+void CustomData_swap(struct CustomData *data, int index, int *corner_indices)
+{
+       const LayerTypeInfo *typeInfo;
+       int i;
+
+       for(i = 0; i < data->totlayer; ++i) {
+               typeInfo = layerType_getInfo(data->layers[i].type);
+
+               if(typeInfo->swap) {
+                       int offset = typeInfo->size * index;
+
+                       typeInfo->swap((char *)data->layers[i].data + offset, corner_indices);
+               }
+       }
 }
 
 void *CustomData_get(const CustomData *data, int index, int type)
@@ -655,8 +783,6 @@ void *CustomData_get(const CustomData *data, int index, int type)
        int offset;
        int layer_index;
        
-       if(index < 0 || index > data->numElems) return NULL;
-
        /* get the layer index of the first layer of type */
        layer_index = CustomData_find_next(data, type, -1);
        if(layer_index < 0) return NULL;
@@ -677,6 +803,18 @@ void *CustomData_get_layer(const CustomData *data, int type)
        return data->layers[layer_index].data;
 }
 
+void *CustomData_set_layer(const CustomData *data, int type, void *ptr)
+{
+       /* get the layer index of the first layer of type */
+       int layer_index = CustomData_find_next(data, type, -1);
+
+       if(layer_index < 0) return NULL;
+
+       data->layers[layer_index].data = ptr;
+
+       return ptr;
+}
+
 void CustomData_set(const CustomData *data, int index, int type, void *source)
 {
        void *dest = CustomData_get(data, index, type);
@@ -690,11 +828,20 @@ void CustomData_set(const CustomData *data, int index, int type, void *source)
                memcpy(dest, source, type_info->size);
 }
 
-void CustomData_set_num_elems(CustomData *data, int numElems)
+void CustomData_set_default(CustomData *data, int index, int count)
 {
-       if(numElems < 0) return;
-       if(numElems < data->maxElems) data->numElems = numElems;
-       else data->numElems = data->maxElems;
+       const LayerTypeInfo *typeInfo;
+       int i;
+
+       for(i = 0; i < data->totlayer; ++i) {
+               typeInfo = layerType_getInfo(data->layers[i].type);
+
+               if(typeInfo->set_default) {
+                       int offset = typeInfo->size * index;
+
+                       typeInfo->set_default((char *)data->layers[i].data + offset, count);
+               }
+       }
 }
 
 /* EditMesh functions */
@@ -706,8 +853,8 @@ void CustomData_em_free_block(CustomData *data, void **block)
 
        if(!*block) return;
 
-    for(i = 0; i < data->numLayers; ++i) {
-        if(!(data->layers[i].flag & LAYERFLAG_NOFREE)) {
+    for(i = 0; i < data->totlayer; ++i) {
+        if(!(data->layers[i].flag & CD_FLAG_NOFREE)) {
             typeInfo = layerType_getInfo(data->layers[i].type);
 
             if(typeInfo->free) {
@@ -728,13 +875,13 @@ static void CustomData_em_alloc_block(CustomData *data, void **block)
        if (*block)
                CustomData_em_free_block(data, block);
 
-       if (data->totSize > 0)
-               *block = MEM_callocN(data->totSize, "CustomData EM block");
+       if (data->totsize > 0)
+               *block = MEM_callocN(data->totsize, "CustomData EM block");
        else
                *block = NULL;
 }
 
-int CustomData_em_copy_data(const CustomData *source, CustomData *dest,
+void CustomData_em_copy_data(const CustomData *source, CustomData *dest,
                             void *src_block, void **dest_block)
 {
        const LayerTypeInfo *type_info;
@@ -745,18 +892,18 @@ int CustomData_em_copy_data(const CustomData *source, CustomData *dest,
        
        /* copies a layer at a time */
        dest_i = 0;
-       for(src_i = 0; src_i < source->numLayers; ++src_i) {
-               if(source->layers[src_i].flag & LAYERFLAG_NOCOPY) continue;
+       for(src_i = 0; src_i < source->totlayer; ++src_i) {
+               if(source->layers[src_i].flag & CD_FLAG_NOCOPY) continue;
 
                /* find the first dest layer with type >= the source type
                 * (this should work because layers are ordered by type)
                 */
-               while(dest_i < dest->numLayers
+               while(dest_i < dest->totlayer
                      && dest->layers[dest_i].type < source->layers[src_i].type)
                        ++dest_i;
 
                /* if there are no more dest layers, we're done */
-               if(dest_i >= dest->numLayers) return 1;
+               if(dest_i >= dest->totlayer) return;
 
                /* if we found a matching layer, copy the data */
                if(dest->layers[dest_i].type == source->layers[src_i].type) {
@@ -777,8 +924,6 @@ int CustomData_em_copy_data(const CustomData *source, CustomData *dest,
                        ++dest_i;
                }
        }
-
-       return 1;
 }
 
 void *CustomData_em_get(const CustomData *data, void *block, int type)
@@ -805,15 +950,13 @@ void CustomData_em_set(CustomData *data, void *block, int type, void *source)
                memcpy(dest, source, type_info->size);
 }
 
-int CustomData_em_interp(CustomData *data, void **src_blocks, float *weights,
-                         float *sub_weights, int count, void *dest_block)
+void CustomData_em_interp(CustomData *data, void **src_blocks, float *weights,
+                          float *sub_weights, int count, void *dest_block)
 {
        int i, j;
        void *source_buf[SOURCE_BUF_SIZE];
        void **sources = source_buf;
 
-       if(count <= 0) return 0;
-
        /* slow fallback in case we're interpolating a ridiculous number of
         * elements
         */
@@ -822,7 +965,7 @@ int CustomData_em_interp(CustomData *data, void **src_blocks, float *weights,
                                      "CustomData_interp sources");
 
        /* interpolates a layer at a time */
-       for(i = 0; i < data->numLayers; ++i) {
+       for(i = 0; i < data->totlayer; ++i) {
                CustomDataLayer *layer = &data->layers[i];
                const LayerTypeInfo *type_info = layerType_getInfo(layer->type);
 
@@ -836,7 +979,6 @@ int CustomData_em_interp(CustomData *data, void **src_blocks, float *weights,
        }
 
        if(count > SOURCE_BUF_SIZE) MEM_freeN(sources);
-       return 1;
 }
 
 void CustomData_em_set_default(CustomData *data, void **block)
@@ -847,13 +989,13 @@ void CustomData_em_set_default(CustomData *data, void **block)
        if (!*block)
                CustomData_em_alloc_block(data, block);
 
-       for(i = 0; i < data->numLayers; ++i) {
+       for(i = 0; i < data->totlayer; ++i) {
                int offset = data->layers[i].offset;
 
                type_info = layerType_getInfo(data->layers[i].type);
 
                if(type_info->set_default)
-                       type_info->set_default((char*)*block + offset);
+                       type_info->set_default((char*)*block + offset, 1);
        }
 }
 
@@ -861,25 +1003,47 @@ void CustomData_to_em_block(const CustomData *source, CustomData *dest,
                             int src_index, void **dest_block)
 {
        const LayerTypeInfo *type_info;
-       int i, src_offset;
+       int dest_i, src_i, src_offset;
 
        if (!*dest_block)
                CustomData_em_alloc_block(dest, dest_block);
        
        /* copies a layer at a time */
-       for(i = 0; i < dest->numLayers; ++i) {
-               int offset = dest->layers[i].offset;
-               char *src_data = source->layers[i].data;
-               char *dest_data = (char*)*dest_block + offset;
+       dest_i = 0;
+       for(src_i = 0; src_i < source->totlayer; ++src_i) {
+               if(source->layers[src_i].flag & CD_FLAG_NOCOPY) continue;
+
+               /* find the first dest layer with type >= the source type
+                * (this should work because layers are ordered by type)
+                */
+               while(dest_i < dest->totlayer
+                     && dest->layers[dest_i].type < source->layers[src_i].type)
+                       ++dest_i;
 
-               type_info = layerType_getInfo(dest->layers[i].type);
-               src_offset = src_index * type_info->size;
+               /* if there are no more dest layers, we're done */
+               if(dest_i >= dest->totlayer) return;
 
-               if(type_info->copy)
-                       type_info->copy(src_data + src_offset, dest_data, 1,
-                                       type_info->size);
-               else
-                       memcpy(dest_data, src_data + src_offset, type_info->size);
+               /* if we found a matching layer, copy the data */
+               if(dest->layers[dest_i].type == source->layers[src_i].type) {
+                       int offset = dest->layers[dest_i].offset;
+                       char *src_data = source->layers[src_i].data;
+                       char *dest_data = (char*)*dest_block + offset;
+
+                       type_info = layerType_getInfo(dest->layers[dest_i].type);
+                       src_offset = src_index * type_info->size;
+
+                       if(type_info->copy)
+                               type_info->copy(src_data + src_offset, dest_data, 1,
+                                                               type_info->size);
+                       else
+                               memcpy(dest_data, src_data + src_offset, type_info->size);
+
+                       /* if there are multiple source & dest layers of the same type,
+                        * we don't want to copy all source layers to the same dest, so
+                        * increment dest_i
+                        */
+                       ++dest_i;
+               }
        }
 }
 
@@ -887,22 +1051,59 @@ void CustomData_from_em_block(const CustomData *source, CustomData *dest,
                               void *src_block, int dest_index)
 {
        const LayerTypeInfo *type_info;
-       int i, dest_offset;
+       int dest_i, src_i, dest_offset;
 
        /* copies a layer at a time */
-       for(i = 0; i < dest->numLayers; ++i) {
-               int offset = source->layers[i].offset;
-               char *src_data = (char*)src_block + offset;
-               char *dest_data = dest->layers[i].data;
+       dest_i = 0;
+       for(src_i = 0; src_i < source->totlayer; ++src_i) {
+               if(source->layers[src_i].flag & CD_FLAG_NOCOPY) continue;
+
+               /* find the first dest layer with type >= the source type
+                * (this should work because layers are ordered by type)
+                */
+               while(dest_i < dest->totlayer
+                     && dest->layers[dest_i].type < source->layers[src_i].type)
+                       ++dest_i;
 
-               type_info = layerType_getInfo(dest->layers[i].type);
-               dest_offset = dest_index * type_info->size;
+               /* if there are no more dest layers, we're done */
+               if(dest_i >= dest->totlayer) return;
 
-               if(type_info->copy)
-                       type_info->copy(src_data, dest_data + dest_offset, 1,
-                                       type_info->size);
-               else
-                       memcpy(dest_data + dest_offset, src_data, type_info->size);
+               /* if we found a matching layer, copy the data */
+               if(dest->layers[dest_i].type == source->layers[src_i].type) {
+                       int offset = source->layers[src_i].offset;
+                       char *src_data = (char*)src_block + offset;
+                       char *dest_data = dest->layers[dest_i].data;
+
+                       type_info = layerType_getInfo(dest->layers[dest_i].type);
+                       dest_offset = dest_index * type_info->size;
+
+                       if(type_info->copy)
+                               type_info->copy(src_data, dest_data + dest_offset, 1,
+                                                               type_info->size);
+                       else
+                               memcpy(dest_data + dest_offset, src_data, type_info->size);
+
+                       /* if there are multiple source & dest layers of the same type,
+                        * we don't want to copy all source layers to the same dest, so
+                        * increment dest_i
+                        */
+                       ++dest_i;
+               }
        }
+
 }
 
+void CustomData_file_write_info(int type, char **structname, int *structnum)
+{
+       const LayerTypeInfo *type_info = layerType_getInfo(type);
+
+       *structname = type_info->structname;
+       *structnum = type_info->structnum;
+}
+
+int CustomData_sizeof(int type)
+{
+       const LayerTypeInfo *type_info = layerType_getInfo(type);
+
+       return type_info->size;
+}
index 5e3439da6bff670c3ddcc044354839c28d89b507..e8ac82fc5969c9a74a9f0da8c6e742a3516153ce 100644 (file)
@@ -86,6 +86,7 @@
 #include "BKE_scene.h"
 #include "BKE_subsurf.h"
 #include "BKE_modifier.h"
+#include "BKE_customdata.h"
 
 #include "RE_pipeline.h"
 #include "RE_shader_ext.h"
 
 static void boundbox_displist(Object *ob);
 
-void displistmesh_free(DispListMesh *dlm) 
-{
-       // also check on mvert and mface, can be NULL after decimator (ton)
-       if (!dlm->dontFreeVerts && dlm->mvert) MEM_freeN(dlm->mvert);
-       if (!dlm->dontFreeNors && dlm->nors) MEM_freeN(dlm->nors);
-       if (!dlm->dontFreeOther) {
-               if (dlm->medge) MEM_freeN(dlm->medge);
-               if (dlm->mface) MEM_freeN(dlm->mface);
-               if (dlm->mcol) MEM_freeN(dlm->mcol);
-               if (dlm->tface) MEM_freeN(dlm->tface);
-       }
-       MEM_freeN(dlm);
-}
-
-DispListMesh *displistmesh_copy(DispListMesh *odlm) 
-{
-       DispListMesh *ndlm= MEM_dupallocN(odlm);
-       ndlm->mvert= MEM_dupallocN(odlm->mvert);
-       if (odlm->medge) ndlm->medge= MEM_dupallocN(odlm->medge);
-       ndlm->mface= MEM_dupallocN(odlm->mface);
-       if (odlm->nors) ndlm->nors = MEM_dupallocN(odlm->nors);
-       if (odlm->mcol) ndlm->mcol= MEM_dupallocN(odlm->mcol);
-       if (odlm->tface) ndlm->tface= MEM_dupallocN(odlm->tface);
-
-       return ndlm;
-}
-
-DispListMesh *displistmesh_copyShared(DispListMesh *odlm) 
-{
-       DispListMesh *ndlm= MEM_dupallocN(odlm);
-       ndlm->dontFreeNors = ndlm->dontFreeOther = ndlm->dontFreeVerts = 1;
-       
-       return ndlm;
-}
-
-void displistmesh_to_mesh(DispListMesh *dlm, Mesh *me) 
-{
-               /* We assume, rather courageously, that any
-                * shared data came from the mesh itself and so
-                * we can ignore the dlm->dontFreeOther flag.
-                */
-
-       if (me->mvert && dlm->mvert!=me->mvert) MEM_freeN(me->mvert);
-       if (me->mface && dlm->mface!=me->mface) MEM_freeN(me->mface);
-       if (me->tface && dlm->tface!=me->tface) MEM_freeN(me->tface);
-       if (me->mcol && dlm->mcol!=me->mcol) MEM_freeN(me->mcol);
-       if (me->medge && dlm->medge!=me->medge) MEM_freeN(me->medge);
-
-       me->tface = NULL;
-       me->mcol = NULL;
-       me->medge = NULL;
-
-       if (dlm->totvert!=me->totvert) {
-               if (me->msticky) MEM_freeN(me->msticky);
-               me->msticky = NULL;
-
-               if (me->dvert) free_dverts(me->dvert, me->totvert);
-               me->dvert = NULL;
-
-               if(me->key) me->key->id.us--;
-               me->key = NULL;
-       }
-
-       me->totface= dlm->totface;
-       me->totvert= dlm->totvert;
-       me->totedge= 0;
-
-       me->mvert= dlm->mvert;
-       me->mface= dlm->mface;
-       if (dlm->tface)
-               me->tface= dlm->tface;
-       if (dlm->mcol)
-               me->mcol= dlm->mcol;
-
-       if(dlm->medge) {
-               me->totedge= dlm->totedge;
-               me->medge= dlm->medge;
-       }
-
-       if (dlm->nors && !dlm->dontFreeNors) MEM_freeN(dlm->nors);
-
-       MEM_freeN(dlm);
-}
-
 void free_disp_elem(DispList *dl)
 {
        if(dl) {
@@ -524,42 +441,50 @@ static void end_fastshade_for_ob(Object *ob)
 static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, unsigned int **col1_r, unsigned int **col2_r)
 {
        Mesh *me= ob->data;
-       int dmNeedsFree;
        DerivedMesh *dm;
-       DispListMesh *dlm;
+       MCol *mcol;
+       MVert *mvert;
+       MFace *mface;
+       MTFace *mtface;
        unsigned int *col1, *col2;
-       float *orco, *vnors, imat[3][3], mat[4][4], vec[3];
-       int a, i, need_orco;
+       float *orco, *vnors, *nors, imat[3][3], mat[4][4], vec[3];
+       int a, i, need_orco, totface, totvert;
 
        init_fastshade_for_ob(re, ob, &need_orco, mat, imat);
 
-       if (need_orco) {
-               orco = mesh_create_orco(ob);
-       } else {
-               orco = NULL;
-       }
+       orco = (need_orco)? mesh_create_orco(ob): NULL;
+
+       if (onlyForMesh)
+               dm = mesh_get_derived_deform(ob);
+       else
+               dm = mesh_get_derived_final(ob);
+       
+       mvert = dm->getVertArray(dm);
+       mface = dm->getFaceArray(dm);
+       mcol = dm->getFaceDataArray(dm, CD_MCOL);
+       mtface = dm->getFaceDataArray(dm, CD_MTFACE);
+       nors = dm->getFaceDataArray(dm, CD_NORMAL);
+       totvert = dm->getNumVerts(dm);
+       totface = dm->getNumFaces(dm);
 
        if (onlyForMesh) {
-               dm = mesh_get_derived_deform(ob, &dmNeedsFree);
+               col1 = *col1_r;
+               col2 = NULL;
        } else {
-               dm = mesh_get_derived_final(ob, &dmNeedsFree);
-       }
-       dlm= dm->convertToDispListMesh(dm, 1);
+               *col1_r = col1 = MEM_mallocN(sizeof(*col1)*totface*4, "col1");
 
-       col1 = MEM_mallocN(sizeof(*col1)*dlm->totface*4, "col1");
-       if (col2_r && (me->flag & ME_TWOSIDED)) {
-               col2 = MEM_mallocN(sizeof(*col2)*dlm->totface*4, "col1");
-       } else {
-               col2 = NULL;
+               if (col2_r && (me->flag & ME_TWOSIDED))
+                       col2 = MEM_mallocN(sizeof(*col2)*totface*4, "col1");
+               else
+                       col2 = NULL;
+               
+               if (col2_r) *col2_r = col2;
        }
-       
-       *col1_r = col1;
-       if (col2_r) *col2_r = col2;
 
                /* vertexnormals */
-       vnors= MEM_mallocN(dlm->totvert*3*sizeof(float), "vnors disp");
-       for (a=0; a<dlm->totvert; a++) {
-               MVert *mv = &dlm->mvert[a];
+       vnors= MEM_mallocN(totvert*3*sizeof(float), "vnors disp");
+       for (a=0; a<totvert; a++) {
+               MVert *mv = &mvert[a];
                float *vn= &vnors[a*3];
                float xn= mv->no[0]; 
                float yn= mv->no[1]; 
@@ -572,9 +497,9 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un
                Normalise(vn);
        }               
 
-       for (i=0; i<dlm->totface; i++) {
-               MFace *mf= &dlm->mface[i];
-               TFace *tface= dlm->tface?&dlm->tface[i]:NULL;
+       for (i=0; i<totface; i++) {
+               MFace *mf= &mface[i];
+               MTFace *tface= (mtface)? &mtface[i]: NULL;
                Material *ma= give_current_material(ob, mf->mat_nr+1);
                int j, vidx[4], nverts= mf->v4?4:3;
                unsigned char *col1base= (unsigned char*) &col1[i*4];
@@ -584,26 +509,20 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un
                
                if(ma==NULL) ma= &defmaterial;
                
-               if (dlm->tface) {
-                       mcolbase = (unsigned char*) dlm->tface[i].col;
-               } else if (dlm->mcol) {
-                       mcolbase = (unsigned char*) &dlm->mcol[i*4];
-               } else {
-                       mcolbase = NULL;
-               }
+               mcolbase = (mcol)? (unsigned char*)&mcol[i*4]: NULL;
 
                vidx[0]= mf->v1;
                vidx[1]= mf->v2;
                vidx[2]= mf->v3;
                vidx[3]= mf->v4;
 
-               if (dlm->nors) {
-                       VECCOPY(nor, &dlm->nors[i*3]);
+               if (nors) {
+                       VECCOPY(nor, &nors[i*3]);
                } else {
                        if (mf->v4)
-                               CalcNormFloat4(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, dlm->mvert[mf->v4].co, nor);
+                               CalcNormFloat4(mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co, nor);
                        else
-                               CalcNormFloat(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, nor);
+                               CalcNormFloat(mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, nor);
                }
 
                n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2];
@@ -612,7 +531,7 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un
                Normalise(n1);
 
                for (j=0; j<nverts; j++) {
-                       MVert *mv= &dlm->mvert[vidx[j]];
+                       MVert *mv= &mvert[vidx[j]];
                        char *col1= (char*)&col1base[j*4];
                        char *col2= (char*)(col2base?&col2base[j*4]:NULL);
                        char *mcol= (char*)(mcolbase?&mcolbase[j*4]:NULL);
@@ -628,13 +547,11 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un
                }
        } 
        MEM_freeN(vnors);
-       displistmesh_free(dlm);
 
-       if (orco) {
+       if (orco)
                MEM_freeN(orco);
-       }
 
-       if (dmNeedsFree) dm->release(dm);
+       dm->release(dm);
 
        end_fastshade_for_ob(ob);
 }
@@ -642,7 +559,7 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un
 void shadeMeshMCol(Object *ob, Mesh *me)
 {
        Render *re= fastshade_get_render();
-       mesh_create_shadedColors(re, ob, 1, (unsigned int**)&me->mcol, NULL);
+       mesh_create_shadedColors(re, ob, 1, (unsigned int **)&me->mcol, NULL);
 }
 
 /* has base pointer, to check for layer */
@@ -1591,43 +1508,3 @@ static void boundbox_displist(Object *ob)
        }
 }
 
-void displistmesh_add_edges(DispListMesh *dlm)
-{
-       EdgeHash *eh = BLI_edgehash_new();
-       EdgeHashIterator *ehi;
-       int i;
-
-       for (i=0; i<dlm->totface; i++) {
-               MFace *mf = &dlm->mface[i];
-
-               if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
-                       BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
-               if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
-                       BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
-               
-               if (mf->v4) {
-                       if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
-                               BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
-                       if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
-                               BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
-               } else {
-                       if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
-                               BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
-               }
-       }
-
-       dlm->totedge = BLI_edgehash_size(eh);
-       dlm->medge = MEM_callocN(dlm->totedge*sizeof(*dlm->medge), "medge");
-
-       ehi = BLI_edgehashIterator_new(eh);
-       for (i=0; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
-               MEdge *med = &dlm->medge[i++];
-
-               BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
-
-               med->flag = ME_EDGEDRAW|ME_EDGERENDER;
-       }
-       BLI_edgehashIterator_free(ehi);
-
-       BLI_edgehash_free(eh, NULL);
-}
index 140d01ec5787837a5ef5562307d3fdd30b4c9eb9..5c37f6b901fcf0552229717e3283a955f30a7877 100644 (file)
 #include "BKE_displist.h"
 #include "BKE_DerivedMesh.h"
 #include "BKE_curve.h"
+#include "BKE_customdata.h"
 
 #include "BPY_extern.h"
 
@@ -297,10 +298,12 @@ static void read_stl_mesh_binary(char *str)
 
                        ob= add_object(OB_MESH);
                        me= ob->data;
-                       me->mvert = vertdata;
-                       me->mface = facedata;
-                       me->totface = totface;
                        me->totvert = totvert;
+                       me->totface = totface;
+                       me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, 0,
+                                                        vertdata, totvert);
+                       me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, 0,
+                                                        facedata, totface);
 
                        mesh_add_normals_flags(me);
                        make_edges(me, 0);
@@ -438,10 +441,13 @@ static void read_stl_mesh_ascii(char *str)
        /* OK, lets create our mesh */
        ob = add_object(OB_MESH);
        me = ob->data;
-       me->mvert = MEM_callocN(totvert*sizeof(MVert), "mverts");
-       me->mface = MEM_callocN(totface*sizeof(MFace), "mface");
+
        me->totface = totface;
        me->totvert = totvert;
+       me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, 0,
+                                        NULL, totvert);
+       me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, 0,
+                                        NULL, totface);
 
        /* Copy vert coords and create topology */
        mvert = me->mvert;
@@ -557,8 +563,10 @@ static void read_videoscape_mesh(char *str)
        me->totvert= verts;
        me->totface= totedge+tottria+totquad;
        
-       me->mvert= MEM_callocN(me->totvert*sizeof(MVert), "mverts");
-       if(me->totface) me->mface= MEM_callocN(me->totface*sizeof(MFace), "mface");
+       me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, 0,
+                                       NULL, me->totvert);
+       me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, 0,
+                                       NULL, me->totface);
        
        /* colors */
        if(totcol) {
@@ -639,7 +647,7 @@ static void read_videoscape_mesh(char *str)
                                        mface->v4= MIN2(nr, me->totvert-1);
                                }
                                
-                               test_index_face(mface, NULL, NULL, poly);
+                               test_index_face(mface, NULL, 0, poly);
                                
                                mface++;
                        }
@@ -761,8 +769,11 @@ static void read_radiogour(char *str)
        me->totvert= verts;
        me->totface= totedge+tottria+totquad;
        me->flag= 0;
-       me->mvert= MEM_callocN(me->totvert*sizeof(MVert), "mverts");
-       if(me->totface) me->mface= MEM_callocN(me->totface*sizeof(MFace), "mface");
+
+       me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, 0,
+                                       NULL, me->totvert);
+       me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, 0,
+                                       NULL, me->totface);
        
        /* verts */
        
@@ -808,7 +819,7 @@ static void read_radiogour(char *str)
                                        mface->v4= MIN2(nr, me->totvert-1);
                                }
                                
-                               test_index_face(mface, NULL, NULL, poly);
+                               test_index_face(mface, NULL, 0, poly);
                                
                                mface++;
                        }
@@ -2054,10 +2065,12 @@ static void displist_to_mesh(DispList *dlfirst)
 
        printf("Import: %d vertices %d faces\n", totvert, totface);
        
-       if(totvert) me->mvert= MEM_callocN(totvert*sizeof(MVert), "mvert");
-       if(totface) me->mface= MEM_callocN(totface*sizeof(MFace), "mface");
        me->totvert= totvert;
        me->totface= totface;
+       me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, 0,
+                                       NULL, me->totvert);
+       me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, 0,
+                                       NULL, me->totface);
        maxvertidx= totvert-1;
        
        mvert= me->mvert;
@@ -2099,7 +2112,7 @@ static void displist_to_mesh(DispList *dlfirst)
                                        mface->v4= p3;
                                        
                                        mface->mat_nr= colnr;
-                                       test_index_face(mface, NULL, NULL, 4);
+                                       test_index_face(mface, NULL, 0, 4);
                                        
                                        mface++;
                                        
@@ -2132,7 +2145,7 @@ static void displist_to_mesh(DispList *dlfirst)
                                                mface->v2= startve+a*dl->nr+1;
                                                mface->v3= startve+a*dl->nr+2;
                                                mface->mat_nr= colnr;
-                                               test_index_face(mface, NULL, NULL, 3);
+                                               test_index_face(mface, NULL, 0, 3);
                                                mface++;
                                        }
                                        else {
@@ -2141,7 +2154,7 @@ static void displist_to_mesh(DispList *dlfirst)
                                                mface->v3= startve+a*dl->nr+2;
                                                mface->v4= startve+a*dl->nr+3;
                                                mface->mat_nr= colnr;
-                                               test_index_face(mface, NULL, NULL, 4);
+                                               test_index_face(mface, NULL, 0, 4);
                                                mface++;
                                        }
                                }
@@ -2196,7 +2209,7 @@ static void displist_to_mesh(DispList *dlfirst)
                                if (mface->v2>maxvertidx) mface->v2= maxvertidx;
                                if (mface->v3>maxvertidx) mface->v3= maxvertidx;
 
-                               test_index_face(mface, NULL, NULL, 3);
+                               test_index_face(mface, NULL, 0, 3);
                                mface++;
                                idata+= 3;
                        }
@@ -2435,40 +2448,42 @@ int BKE_read_exotic(char *name)
 
 char videosc_dir[160]= {0, 0};
 
-#define WRITEVERT(verts, ind) {           \
-  VECCOPY(vert, verts[(ind)].co);         \
-  Mat4MulVecfl(ob->obmat, vert);          \
-  if (G.order==B_ENDIAN) {                \
-    SWITCH_INT(vert[0]);                \
-    SWITCH_INT(vert[1]);                \
-    SWITCH_INT(vert[2]);                \
-  }                                       \
-  fwrite(vert, sizeof(float), 3, fpSTL);  \
+static void write_vert_stl(Object *ob, MVert *verts, int index, FILE *fpSTL)
+{
+       float vert[3];
+
+       VECCOPY(vert, verts[(index)].co);
+       Mat4MulVecfl(ob->obmat, vert);
+
+       if (G.order==B_ENDIAN) {
+               SWITCH_INT(vert[0]);
+               SWITCH_INT(vert[1]);
+               SWITCH_INT(vert[2]);
+       }
+
+       fwrite(vert, sizeof(float), 3, fpSTL);
 }
 
-static int write_displistmesh_stl(FILE *fpSTL, Object *ob, DispListMesh *dlm)
+static int write_derivedmesh_stl(FILE *fpSTL, Object *ob, DerivedMesh *dm)
 {
-
-       MFace *mface;
-       int  i, numfacets = 0;
+       MVert *mvert = dm->getVertArray(dm);
+       MFace *mface = dm->getFaceArray(dm);
+       int i, numfacets = 0, totface = dm->getNumFaces(dm);;
        float zero[3] = {0.0f, 0.0f, 0.0f};
-       float vert[3];
-
-       for (i=0; i<dlm->totface; i++) {
-               mface = &dlm->mface[i];
 
+       for (i=0; i<totface; i++, mface++) {
                fwrite(zero, sizeof(float), 3, fpSTL);
-               WRITEVERT(dlm->mvert, mface->v1);
-               WRITEVERT(dlm->mvert, mface->v2);
-               WRITEVERT(dlm->mvert, mface->v3);
+               write_vert_stl(ob, mvert, mface->v1, fpSTL);
+               write_vert_stl(ob, mvert, mface->v2, fpSTL);
+               write_vert_stl(ob, mvert, mface->v3, fpSTL);
                fprintf(fpSTL, "  ");
                numfacets++;
 
                if(mface->v4) { /* quad = 2 tri's */
                        fwrite(zero, sizeof(float), 3, fpSTL);
-                       WRITEVERT(dlm->mvert, mface->v1);
-                       WRITEVERT(dlm->mvert, mface->v3);
-                       WRITEVERT(dlm->mvert, mface->v4);
+                       write_vert_stl(ob, mvert, mface->v1, fpSTL);
+                       write_vert_stl(ob, mvert, mface->v3, fpSTL);
+                       write_vert_stl(ob, mvert, mface->v4, fpSTL);
                        fprintf(fpSTL, "  ");
                        numfacets++;
                }
@@ -2480,14 +2495,11 @@ static int write_displistmesh_stl(FILE *fpSTL, Object *ob, DispListMesh *dlm)
 static int write_object_stl(FILE *fpSTL, Object *ob, Mesh *me)
 {
        int  numfacets = 0;
-       int dmNeedsFree;
-       DerivedMesh *dm = mesh_get_derived_final(ob, &dmNeedsFree);
-       DispListMesh *dlm = dm->convertToDispListMesh(dm, 1);
+       DerivedMesh *dm = mesh_get_derived_final(ob);
 
-       numfacets += write_displistmesh_stl(fpSTL, ob, dlm);
+       numfacets += write_derivedmesh_stl(fpSTL, ob, dm);
 
-       displistmesh_free(dlm);
-       if (dmNeedsFree) dm->release(dm);
+       dm->release(dm);
 
        return numfacets;
 }
@@ -2637,8 +2649,7 @@ static void write_videoscape_mesh(Object *ob, char *str)
                }
        }
        else {
-               int needsFree;
-               DerivedMesh *dm = mesh_get_derived_deform(ob, &needsFree);
+               DerivedMesh *dm = mesh_get_derived_deform(ob);
                
                me= ob->data;
                
@@ -2659,8 +2670,7 @@ static void write_videoscape_mesh(Object *ob, char *str)
                        }
                }
 
-               if (needsFree)
-                       dm->release(dm);
+               dm->release(dm);
        }
        
        fclose(fp);
@@ -2798,7 +2808,7 @@ static void write_mesh_vrml(FILE *fp, Mesh *me)
        Material *ma;
        MVert *mvert;
        MFace *mface;
-       TFace *tface;
+       MTFace *tface;
        Image *ima;
        int a, b, totcol, texind;
        char str[32];
@@ -2808,8 +2818,8 @@ static void write_mesh_vrml(FILE *fp, Mesh *me)
        fprintf(fp, "\tDEF %s\n", str);
        fprintf(fp, "\tSeparator {\n");
        
-       if(me->tface) {
-               ima= ((TFace *)me->tface)->tpage;
+       if(me->mtface) {
+               ima= ((MTFace *)me->mtface)->tpage;
                if(ima) {
                        fprintf(fp, "\t\tTexture2 {\n");
                        fprintf(fp, "\t\t\tfilename %s\n", ima->name);
@@ -2817,7 +2827,6 @@ static void write_mesh_vrml(FILE *fp, Mesh *me)
                        fprintf(fp, "\t\t\twrapT REPEAT \n");
                        fprintf(fp, "\t\t}\n");
                }
-               tface_to_mcol(me);
        }
        
        if(me->mcol) {
@@ -2874,13 +2883,13 @@ static void write_mesh_vrml(FILE *fp, Mesh *me)
                        }
                }
                
-               if(me->tface) {
+               if(me->mtface) {
                        fprintf(fp, "\t\tTextureCoordinate2 {\n");
                        fprintf(fp, "\t\t\tpoint [\n");
        
                        a= me->totface;
                        mface= me->mface;
-                       tface= me->tface;
+                       tface= me->mtface;
                        while(a--) {
                                if(mface->mat_nr==b) {
                                        fprintf(fp, "\t\t\t\t %f %f,\n", tface->uv[0][0], tface->uv[0][1]); 
@@ -2909,7 +2918,7 @@ static void write_mesh_vrml(FILE *fp, Mesh *me)
                }
                fprintf(fp, "\t\t\t]\n");
 
-               if(me->tface) {
+               if(me->mtface) {
                        fprintf(fp, "\t\t\ttextureCoordIndex [\n");
        
                        a= me->totface;
@@ -2933,12 +2942,6 @@ static void write_mesh_vrml(FILE *fp, Mesh *me)
        }
        
        fprintf(fp, "\t}\n");
-       
-       if(me->tface) {
-               MEM_freeN(me->mcol);
-               me->mcol= 0;
-       }
-
 }
 
 static void write_camera_vrml(FILE *fp, Object *ob)
@@ -3637,8 +3640,8 @@ static void dxf_get_mesh(Mesh** m, Object** o, int noob)
        }
        me->totvert=0;
        me->totface=0;
-       me->mvert=NULL;
-       me->mface=NULL;
+       me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, 0, NULL, 0);
+       me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, 0, NULL, 0);
 }
 
 static void dxf_read_point(int noob) { 
@@ -3673,7 +3676,8 @@ static void dxf_read_point(int noob) {
        dxf_get_mesh(&me, &ob, noob);
        me->totvert= 1;
        me->mvert= MEM_callocN(me->totvert*sizeof(MVert), "mverts");
-                                       
+       CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert);
+       
        dxf_add_mat (ob, me, color, layname);                                   
 
        mvert= me->mvert;
@@ -3772,14 +3776,14 @@ static void dxf_read_line(int noob) {
                memcpy(vtmp, me->mvert, (me->totvert-2)*sizeof(MVert));
                MEM_freeN(me->mvert);
        }
-       me->mvert= vtmp;
+       me->mvert= CustomData_set_layer(&me->vdata, CD_MVERT, vtmp);
        vtmp=NULL;
 
        if(me->mface) {
                memcpy(ftmp, me->mface, (me->totface-1)*sizeof(MFace));
                MEM_freeN(me->mface);
        }
-       me->mface= ftmp;
+       me->mface= CustomData_set_layer(&me->fdata, CD_MFACE, ftmp);
        ftmp=NULL;
        
        mvert= &me->mvert[(me->totvert-2)];
@@ -3972,6 +3976,9 @@ static void dxf_read_ellipse(int noob)
        me->mvert = (MVert*) MEM_callocN(me->totvert*sizeof(MVert), "mverts");
        me->mface = (MFace*) MEM_callocN(me->totface*sizeof(MVert), "mface");
 
+       CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert);
+       CustomData_set_layer(&me->fdata, CD_MFACE, me->mface);
+
        printf("vertex and face buffers allocated\n");
 
        for(v = 0; v <= tot; v++) {
@@ -4096,6 +4103,9 @@ static void dxf_read_arc(int noob)
        me->mvert = (MVert*) MEM_callocN(me->totvert*sizeof(MVert), "mverts");
        me->mface = (MFace*) MEM_callocN(me->totface*sizeof(MVert), "mface");
 
+       CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert);
+       CustomData_set_layer(&me->fdata, CD_MFACE, me->mface);
+
        for(v = 0; v <= tot; v++) { 
 
                epoint[0]= center[0]+dia*sin(phi);
@@ -4236,7 +4246,7 @@ static void dxf_read_polyline(int noob) {
                                memcpy (vtmp, me->mvert, (me->totvert-1)*sizeof(MVert));
                                MEM_freeN(me->mvert);
                        }
-                       me->mvert= vtmp;
+                       me->mvert= CustomData_set_layer(&me->vdata, CD_MVERT, vtmp);
                        vtmp= NULL;
                        
                        mvert= &me->mvert[me->totvert-1];
@@ -4258,7 +4268,7 @@ static void dxf_read_polyline(int noob) {
                                memcpy(ftmp, me->mface, oldtotface*sizeof(MFace));
                                MEM_freeN(me->mface);
                        }
-                       me->mface= ftmp;
+                       me->mface= CustomData_set_layer(&me->fdata, CD_MFACE, ftmp);
                        ftmp=NULL;
 
                        mface= me->mface;
@@ -4348,7 +4358,7 @@ static void dxf_read_polyline(int noob) {
                                        memcpy(vtmp, me->mvert, (me->totvert-1)*sizeof(MVert));
                                        MEM_freeN(me->mvert);
                                }
-                               me->mvert= vtmp;
+                               me->mvert= CustomData_set_layer(&me->vdata, CD_MVERT, vtmp);
                                vtmp=NULL;
                                
                                mvert= &me->mvert[(me->totvert-1)];
@@ -4373,7 +4383,7 @@ static void dxf_read_polyline(int noob) {
                                        memcpy(ftmp, me->mface, (me->totface-1)*sizeof(MFace));
                                        MEM_freeN(me->mface);
                                }
-                               me->mface= ftmp;
+                               me->mface= CustomData_set_layer(&me->fdata, CD_MFACE, ftmp);
                                ftmp=NULL;                      
                                
                                mface= &(((MFace*)me->mface)[me->totface-1]);
@@ -4383,9 +4393,9 @@ static void dxf_read_polyline(int noob) {
        
                                if(vids[3] && vids[3]!=vids[0]) {
                                        mface->v4= vids[3]-1;
-                                       test_index_face(mface, NULL, NULL, 4);
+                                       test_index_face(mface, NULL, 0, 4);
                                }
-                               else test_index_face(mface, NULL, NULL, 3);
+                               else test_index_face(mface, NULL, 0, 3);
        
                                mface->mat_nr= 0;
        
@@ -4458,9 +4468,13 @@ static void dxf_read_lwpolyline(int noob) {
 
        me->totvert += nverts;
        me->totface += nverts;
+
        me->mvert = (MVert*) MEM_callocN(me->totvert*sizeof(MVert), "mverts");
        me->mface = (MFace*) MEM_callocN(me->totface*sizeof(MVert), "mface");
 
+       CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert);
+       CustomData_set_layer(&me->fdata, CD_MFACE, me->mface);
+
        for (v = 0; v < nverts; v++) {
                read_group(id,val);
                if (id == 10) {
@@ -4668,14 +4682,14 @@ static void dxf_read_3dface(int noob)
                memcpy(vtmp, me->mvert, (me->totvert-nverts)*sizeof(MVert));
                MEM_freeN(me->mvert);
        }
-       me->mvert= vtmp;
+       me->mvert= CustomData_set_layer(&me->vdata, CD_MVERT, vtmp);
        vtmp=NULL;
 
        if(me->mface) {
                memcpy(ftmp, me->mface, (me->totface-1)*sizeof(MFace));
                MEM_freeN(me->mface);
        }
-       me->mface= ftmp;
+       me->mface= CustomData_set_layer(&me->fdata, CD_MFACE, ftmp);
        ftmp=NULL;
        
        mvert= &me->mvert[(me->totvert-nverts)];
@@ -4705,7 +4719,7 @@ static void dxf_read_3dface(int noob)
 
        mface->mat_nr= 0;
 
-       test_index_face(mface, NULL, NULL, nverts);
+       test_index_face(mface, NULL, 0, nverts);
 
        hasbumped=1;
 }
index 813cd428ab53d2adedf8282e34e8fc8e067cca2a..3eed967c0c94f312703723fb7aa2ddba950f8acb 100644 (file)
@@ -623,7 +623,7 @@ void curve_deform_verts(Object *cuOb, Object *target, DerivedMesh *dm, float (*v
         */
        if(target && target->type==OB_MESH) {
                /* if there's derived data without deformverts, don't use vgroups */
-               if(dm && !dm->getVertData(dm, 0, LAYERTYPE_MDEFORMVERT))
+               if(dm && !dm->getVertData(dm, 0, CD_MDEFORMVERT))
                        use_vgroups = 0;
                else
                        use_vgroups = 1;
@@ -649,7 +649,7 @@ void curve_deform_verts(Object *cuOb, Object *target, DerivedMesh *dm, float (*v
                        INIT_MINMAX(cd.dmin, cd.dmax);
 
                        for(a = 0; a < numVerts; a++, dvert++) {
-                               if(dm) dvert = dm->getVertData(dm, a, LAYERTYPE_MDEFORMVERT);
+                               if(dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT);
 
                                for(j = 0; j < dvert->totweight; j++) {
                                        if(dvert->dw[j].def_nr == index) {
@@ -662,7 +662,7 @@ void curve_deform_verts(Object *cuOb, Object *target, DerivedMesh *dm, float (*v
 
                        dvert = me->dvert;
                        for(a = 0; a < numVerts; a++, dvert++) {
-                               if(dm) dvert = dm->getVertData(dm, a, LAYERTYPE_MDEFORMVERT);
+                               if(dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT);
 
                                for(j = 0; j < dvert->totweight; j++) {
                                        if(dvert->dw[j].def_nr == index) {
@@ -736,7 +736,7 @@ void lattice_deform_verts(Object *laOb, Object *target, DerivedMesh *dm,
         */
        if(target && target->type==OB_MESH) {
                /* if there's derived data without deformverts, don't use vgroups */
-               if(dm && !dm->getVertData(dm, 0, LAYERTYPE_MDEFORMVERT))
+               if(dm && !dm->getVertData(dm, 0, CD_MDEFORMVERT))
                        use_vgroups = 0;
                else
                        use_vgroups = 1;
@@ -758,7 +758,7 @@ void lattice_deform_verts(Object *laOb, Object *target, DerivedMesh *dm,
                        int j;
                        
                        for(a = 0; a < numVerts; a++, dvert++) {
-                               if(dm) dvert = dm->getVertData(dm, a, LAYERTYPE_MDEFORMVERT);
+                               if(dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT);
                                for(j = 0; j < dvert->totweight; j++) {
                                        if (dvert->dw[j].def_nr == index) {
                                                calc_latt_deform(vertexCos[a], dvert->dw[j].weight);
index 1d443be5be26d449de6f978b942f91d75797dc19..43eb77ec86797c4d28bf60f9c8815c0637ba893b 100644 (file)
@@ -57,6 +57,7 @@
 
 #include "BDR_sculptmode.h"
 
+#include "BKE_customdata.h"
 #include "BKE_depsgraph.h"
 #include "BKE_main.h"
 #include "BKE_DerivedMesh.h"
@@ -84,9 +85,7 @@
 
 #include "multires.h"
 
-
-
-int update_realtime_texture(TFace *tface, double time)
+int update_realtime_texture(MTFace *tface, double time)
 {
        Image *ima;
        int     inc = 0;
@@ -125,6 +124,19 @@ int update_realtime_texture(TFace *tface, double time)
        return inc;
 }
 
+void mesh_update_customdata_pointers(Mesh *me)
+{
+       me->mvert = CustomData_get_layer(&me->vdata, CD_MVERT);
+       me->dvert = CustomData_get_layer(&me->vdata, CD_MDEFORMVERT);
+       me->msticky = CustomData_get_layer(&me->vdata, CD_MSTICKY);
+
+       me->medge = CustomData_get_layer(&me->edata, CD_MEDGE);
+
+       me->mface = CustomData_get_layer(&me->fdata, CD_MFACE);
+       me->mcol = CustomData_get_layer(&me->fdata, CD_MCOL);
+       me->mtface = CustomData_get_layer(&me->fdata, CD_MTFACE);
+}
+
 /* Note: unlinking is called when me->id.us is 0, question remains how
  * much unlinking of Library data in Mesh should be done... probably
  * we need a more generic method, like the expand() functions in
@@ -165,14 +177,9 @@ void free_mesh(Mesh *me)
                MEM_freeN(me->pv);
        }
 
-       if(me->mvert) MEM_freeN(me->mvert);
-       if(me->medge) MEM_freeN(me->medge);
-       if(me->mface) MEM_freeN(me->mface);
-       
-       if(me->tface) MEM_freeN(me->tface);
-       if(me->dvert) free_dverts(me->dvert, me->totvert);
-       if(me->mcol) MEM_freeN(me->mcol);
-       if(me->msticky) MEM_freeN(me->msticky);
+       CustomData_free(&me->vdata, me->totvert);
+       CustomData_free(&me->edata, me->totedge);
+       CustomData_free(&me->fdata, me->totface);
 
        if(me->mat) MEM_freeN(me->mat);
        
@@ -200,6 +207,7 @@ void copy_dverts(MDeformVert *dst, MDeformVert *src, int copycount)
        }
 
 }
+
 void free_dverts(MDeformVert *dvert, int totvert)
 {
        /* Instead of freeing the verts directly,
@@ -249,26 +257,20 @@ Mesh *copy_mesh(Mesh *me)
        }
        id_us_plus((ID *)men->texcomesh);
 
-       men->mvert= MEM_dupallocN(me->mvert);
-       men->medge= MEM_dupallocN(me->medge);
-       men->mface= MEM_dupallocN(me->mface);
-       men->tface= MEM_dupallocN(me->tface);
-       men->dface= NULL;
-       men->mselect= NULL;
-       
-       if (me->dvert){
-               men->dvert = MEM_mallocN (sizeof (MDeformVert)*me->totvert, "MDeformVert");
-               copy_dverts(men->dvert, me->dvert, me->totvert);
-       }
-       if (me->tface){
+       CustomData_copy(&me->vdata, &men->vdata, CD_MASK_MESH, CD_DUPLICATE, men->totvert);
+       CustomData_copy(&me->edata, &men->edata, CD_MASK_MESH, CD_DUPLICATE, men->totedge);
+       CustomData_copy(&me->fdata, &men->fdata, CD_MASK_MESH, CD_DUPLICATE, men->totface);
+       mesh_update_customdata_pointers(men);
+
+       if (me->mtface){
                /* ensure indirect linked data becomes lib-extern */
-               TFace *tface= me->tface;
+               MTFace *tface= me->mtface;
                for(a=0; a<me->totface; a++, tface++)
                        if(tface->tpage)
-                               id_lib_extern(tface->tpage);
+                               id_lib_extern((ID*)tface->tpage);
        }
-       men->mcol= MEM_dupallocN(me->mcol);
-       men->msticky= MEM_dupallocN(me->msticky);
+
+       men->mselect= NULL;
 
        men->bb= MEM_dupallocN(men->bb);
        
@@ -284,14 +286,14 @@ Mesh *copy_mesh(Mesh *me)
 
 void make_local_tface(Mesh *me)
 {
-       TFace *tface;
+       MTFace *tface;
        Image *ima;
        int a;
        
-       if(me->tface==0) return;
+       if(me->mtface==0) return;
        
        a= me->totface;
-       tface= me->tface;
+       tface= me->mtface;
        while(a--) {
                
                /* special case: ima always local immediately */
@@ -325,7 +327,7 @@ void make_local_mesh(Mesh *me)
                me->id.flag= LIB_LOCAL;
                new_id(0, (ID *)me, 0);
                
-               if(me->tface) make_local_tface(me);
+               if(me->mtface) make_local_tface(me);
                
                return;
        }
@@ -344,7 +346,7 @@ void make_local_mesh(Mesh *me)
                me->id.flag= LIB_LOCAL;
                new_id(0, (ID *)me, 0);
                
-               if(me->tface) make_local_tface(me);
+               if(me->mtface) make_local_tface(me);
                
        }
        else if(local && lib) {
@@ -535,11 +537,9 @@ float *mesh_create_orco(Object *ob)
 
 /* rotates the vertices of a face in case v[2] or v[3] (vertex index) is = 0.
    this is necessary to make the if(mface->v4) check for quads work */
-#define UVSWAP(t, s) { SWAP(float, t[0], s[0]); SWAP(float, t[1], s[1]); }
-void test_index_face(MFace *mface, MCol *mc, TFace *tface, int nr)
+void test_index_face(MFace *mface, CustomData *fdata, int mfindex, int nr)
 {
        /* first test if the face is legal */
-
        if(mface->v3 && mface->v3==mface->v4) {
                mface->v4= 0;
                nr--;
@@ -559,39 +559,22 @@ void test_index_face(MFace *mface, MCol *mc, TFace *tface, int nr)
        /* prevent a zero at wrong index location */
        if(nr==3) {
                if(mface->v3==0) {
+                       static int corner_indices[4] = {1, 2, 0, 3};
+
                        SWAP(int, mface->v1, mface->v2);
                        SWAP(int, mface->v2, mface->v3);
 
-                       if (tface) {
-                               UVSWAP(tface->uv[0], tface->uv[1]);
-                               UVSWAP(tface->uv[1], tface->uv[2]);
-                               SWAP(unsigned int, tface->col[0], tface->col[1]);
-                               SWAP(unsigned int, tface->col[1], tface->col[2]);
-                       }
-
-                       if (mc) {
-                               SWAP(MCol, mc[0], mc[1]);
-                               SWAP(MCol, mc[1], mc[2]);
-                       }
+                       CustomData_swap(fdata, mfindex, corner_indices);
                }
        }
        else if(nr==4) {
                if(mface->v3==0 || mface->v4==0) {
+                       static int corner_indices[4] = {2, 3, 0, 1};
+
                        SWAP(int, mface->v1, mface->v3);
                        SWAP(int, mface->v2, mface->v4);
 
-
-                       if (tface) {
-                               UVSWAP(tface->uv[0], tface->uv[2]);
-                               UVSWAP(tface->uv[1], tface->uv[3]);
-                               SWAP(unsigned int, tface->col[0], tface->col[2]);
-                               SWAP(unsigned int, tface->col[1], tface->col[3]);
-                       }
-
-                       if (mc) {
-                               SWAP(MCol, mc[0], mc[2]);
-                               SWAP(MCol, mc[1], mc[3]);
-                       }
+                       CustomData_swap(fdata, mfindex, corner_indices);
                }
        }
 }
@@ -652,7 +635,6 @@ static int vergedgesort(const void *v1, const void *v2)
        return 0;
 }
 
-
 void make_edges(Mesh *me, int old)
 {
        MFace *mface;
@@ -669,7 +651,7 @@ void make_edges(Mesh *me, int old)
        }
        
        if(totedge==0) {
-                       /* flag that mesh has edges */
+               /* flag that mesh has edges */
                me->medge = MEM_callocN(0, "make mesh edges");
                me->totedge = 0;
                return;
@@ -699,7 +681,8 @@ void make_edges(Mesh *me, int old)
        }
        final++;
        
-       medge= me->medge= MEM_callocN(final*sizeof(MEdge), "make mesh edges");
+
+       medge= me->medge= CustomData_add_layer(&me->edata, CD_MEDGE, 0, NULL, final);
        me->totedge= final;
        
        for(a=totedge, ed=edsort; a>1; a--, ed++) {
@@ -736,8 +719,8 @@ void mesh_strip_loose_faces(Mesh *me)
                if (me->mface[a].v3) {
                        if (a!=b) {
                                memcpy(&me->mface[b],&me->mface[a],sizeof(me->mface[b]));
-                               if (me->tface) memcpy(&me->tface[b],&me->tface[a],sizeof(me->tface[b]));
-                               if (me->mcol) memcpy(&me->mcol[b*4],&me->mcol[a*4],sizeof(me->mcol[b])*4);
+                               CustomData_copy_data(&me->fdata, &me->fdata, a, b, 1);
+                               CustomData_free_elem(&me->fdata, a, 1);
                        }
                        b++;
                }
@@ -762,7 +745,11 @@ void mball_to_mesh(ListBase *lb, Mesh *me)
                me->totvert= dl->nr;
                me->totface= dl->parts;
                
-               me->mvert=mvert= MEM_callocN(dl->nr*sizeof(MVert), "mverts");
+               mvert= CustomData_add_layer(&me->vdata, CD_MVERT, 0, NULL, dl->nr);
+               mface= CustomData_add_layer(&me->fdata, CD_MFACE, 0, NULL, dl->parts);
+               me->mvert= mvert;
+               me->mface= mface;
+
                a= dl->nr;
                nors= dl->nors;
                verts= dl->verts;
@@ -776,7 +763,6 @@ void mball_to_mesh(ListBase *lb, Mesh *me)
                        verts+= 3;
                }
                
-               me->mface=mface= MEM_callocN(dl->parts*sizeof(MFace), "mface");
                a= dl->parts;
                index= dl->index;
                while(a--) {
@@ -789,6 +775,8 @@ void mball_to_mesh(ListBase *lb, Mesh *me)
                        mface++;
                        index+= 4;
                }
+
+               make_edges(me, 0);      // all edges
        }       
 }
 
@@ -845,8 +833,10 @@ void nurbs_to_mesh(Object *ob)
        cu->mat= 0;
        cu->totcol= 0;
 
-       mvert=me->mvert= MEM_callocN(me->totvert*sizeof(MVert), "cumesh1");
-       mface=me->mface= MEM_callocN(me->totface*sizeof(MFace), "cumesh2");
+       mvert= CustomData_add_layer(&me->vdata, CD_MVERT, 0, NULL, me->totvert);
+       mface= CustomData_add_layer(&me->fdata, CD_MFACE, 0, NULL, me->totface);
+       me->mvert= mvert;
+       me->mface= mface;
 
        /* verts and faces */
        vertcount= 0;
@@ -916,7 +906,7 @@ void nurbs_to_mesh(Object *ob)
                                mface->v2= startvert+index[1];
                                mface->v3= startvert+index[2];
                                mface->v4= 0;
-                               test_index_face(mface, NULL, NULL, 3);
+                               test_index_face(mface, NULL, 0, 3);
                                
                                mface++;
                                index+= 3;
@@ -964,7 +954,7 @@ void nurbs_to_mesh(Object *ob)
                                        mface->v3= p4;
                                        mface->v4= p2;
                                        mface->mat_nr= (unsigned char)dl->col;
-                                       test_index_face(mface, NULL, NULL, 4);
+                                       test_index_face(mface, NULL, 0, 4);
                                        mface++;
 
                                        p4= p3; 
@@ -980,7 +970,7 @@ void nurbs_to_mesh(Object *ob)
        }
 
        make_edges(me, 0);      // all edges
-       mesh_strip_loose_faces(me);
+       mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
 
        if(ob->data) {
                free_libblock(&G