Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/DerivedMesh.c')
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c822
1 files changed, 678 insertions, 144 deletions
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 27aeeb95903..573edb78687 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -31,7 +31,7 @@
#include <string.h>
-
+#include "limits.h"
#include "MEM_guardedalloc.h"
@@ -46,6 +46,7 @@
#include "BLI_editVert.h"
#include "BLI_math.h"
#include "BLI_memarena.h"
+#include "BLI_array.h"
#include "BLI_pbvh.h"
#include "BLI_utildefines.h"
#include "BLI_linklist.h"
@@ -60,6 +61,9 @@
#include "BKE_texture.h"
#include "BKE_multires.h"
#include "BKE_armature.h"
+#include "BKE_particle.h"
+#include "BKE_tessmesh.h"
+#include "BKE_bvhutils.h"
#include "BKE_deform.h"
#ifdef WITH_GAMEENGINE
@@ -78,6 +82,9 @@ static DerivedMesh *navmesh_dm_createNavMeshForVisualization(DerivedMesh *dm);
extern GLubyte stipple_quarttone[128]; /* glutil.c, bad level data */
+static void add_shapekey_layers(DerivedMesh *dm, Mesh *me, Object *ob);
+static void shapekey_layers_to_keyblocks(DerivedMesh *dm, Mesh *me, int actshape_uid);
+
///////////////////////////////////
///////////////////////////////////
@@ -109,20 +116,48 @@ static MEdge *dm_getEdgeArray(DerivedMesh *dm)
return medge;
}
-static MFace *dm_getFaceArray(DerivedMesh *dm)
+static MFace *dm_getTessFaceArray(DerivedMesh *dm)
{
MFace *mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
if (!mface) {
mface = CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL,
- dm->getNumFaces(dm));
+ dm->getNumTessFaces(dm));
CustomData_set_layer_flag(&dm->faceData, CD_MFACE, CD_FLAG_TEMPORARY);
- dm->copyFaceArray(dm, mface);
+ dm->copyTessFaceArray(dm, mface);
}
return mface;
}
+static MLoop *dm_getLoopArray(DerivedMesh *dm)
+{
+ MLoop *mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
+
+ if (!mloop) {
+ mloop = CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL,
+ dm->getNumLoops(dm));
+ CustomData_set_layer_flag(&dm->loopData, CD_MLOOP, CD_FLAG_TEMPORARY);
+ dm->copyLoopArray(dm, mloop);
+ }
+
+ return mloop;
+}
+
+static MPoly *dm_getPolyArray(DerivedMesh *dm)
+{
+ MPoly *mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
+
+ if (!mpoly) {
+ mpoly = CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL,
+ dm->getNumPolys(dm));
+ CustomData_set_layer_flag(&dm->polyData, CD_MPOLY, CD_FLAG_TEMPORARY);
+ dm->copyPolyArray(dm, mpoly);
+ }
+
+ return mpoly;
+}
+
static MVert *dm_dupVertArray(DerivedMesh *dm)
{
MVert *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumVerts(dm),
@@ -145,41 +180,98 @@ static MEdge *dm_dupEdgeArray(DerivedMesh *dm)
static MFace *dm_dupFaceArray(DerivedMesh *dm)
{
- MFace *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumFaces(dm),
+ MFace *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumTessFaces(dm),
"dm_dupFaceArray tmp");
- if(tmp) dm->copyFaceArray(dm, tmp);
+ if(tmp) dm->copyTessFaceArray(dm, tmp);
return tmp;
}
+static MLoop *dm_dupLoopArray(DerivedMesh *dm)
+{
+ MLoop *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumLoops(dm),
+ "dm_dupLoopArray tmp");
+
+ if(tmp) dm->copyLoopArray(dm, tmp);
+
+ return tmp;
+}
+
+static MPoly *dm_dupPolyArray(DerivedMesh *dm)
+{
+ MPoly *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumPolys(dm),
+ "dm_dupPolyArray tmp");
+
+ if(tmp) dm->copyPolyArray(dm, tmp);
+
+ return tmp;
+}
+
+static CustomData *dm_getVertCData(DerivedMesh *dm)
+{
+ return &dm->vertData;
+}
+
+static CustomData *dm_getEdgeCData(DerivedMesh *dm)
+{
+ return &dm->edgeData;
+}
+
+static CustomData *dm_getTessFaceCData(DerivedMesh *dm)
+{
+ return &dm->faceData;
+}
+
+static CustomData *dm_getLoopCData(DerivedMesh *dm)
+{
+ return &dm->loopData;
+}
+
+static CustomData *dm_getPolyCData(DerivedMesh *dm)
+{
+ return &dm->polyData;
+}
+
void DM_init_funcs(DerivedMesh *dm)
{
/* default function implementations */
dm->getVertArray = dm_getVertArray;
dm->getEdgeArray = dm_getEdgeArray;
- dm->getFaceArray = dm_getFaceArray;
+ dm->getTessFaceArray = dm_getTessFaceArray;
+ dm->getLoopArray = dm_getLoopArray;
+ dm->getPolyArray = dm_getPolyArray;
dm->dupVertArray = dm_dupVertArray;
dm->dupEdgeArray = dm_dupEdgeArray;
- dm->dupFaceArray = dm_dupFaceArray;
+ dm->dupTessFaceArray = dm_dupFaceArray;
+ dm->dupLoopArray = dm_dupLoopArray;
+ dm->dupPolyArray = dm_dupPolyArray;
+
+ dm->getVertDataLayout = dm_getVertCData;
+ dm->getEdgeDataLayout = dm_getEdgeCData;
+ dm->getTessFaceDataLayout = dm_getTessFaceCData;
+ dm->getLoopDataLayout = dm_getLoopCData;
+ dm->getPolyDataLayout = dm_getPolyCData;
dm->getVertData = DM_get_vert_data;
dm->getEdgeData = DM_get_edge_data;
- dm->getFaceData = DM_get_face_data;
+ dm->getTessFaceData = DM_get_tessface_data;
dm->getVertDataArray = DM_get_vert_data_layer;
dm->getEdgeDataArray = DM_get_edge_data_layer;
- dm->getFaceDataArray = DM_get_face_data_layer;
+ dm->getTessFaceDataArray = DM_get_tessface_data_layer;
bvhcache_init(&dm->bvhCache);
}
-void DM_init(DerivedMesh *dm, DerivedMeshType type,
- int numVerts, int numEdges, int numFaces)
+void DM_init(DerivedMesh *dm, DerivedMeshType type, int numVerts, int numEdges,
+ int numTessFaces, int numLoops, int numPolys)
{
dm->type = type;
dm->numVertData = numVerts;
dm->numEdgeData = numEdges;
- dm->numFaceData = numFaces;
+ dm->numTessFaceData = numTessFaces;
+ dm->numLoopData = numLoops;
+ dm->numPolyData = numPolys;
DM_init_funcs(dm);
@@ -188,19 +280,26 @@ void DM_init(DerivedMesh *dm, DerivedMeshType type,
}
void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type,
- int numVerts, int numEdges, int numFaces)
+ int numVerts, int numEdges, int numTessFaces,
+ int numLoops, int numPolys)
{
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);
+ CD_CALLOC, numTessFaces);
+ CustomData_copy(&source->loopData, &dm->loopData, CD_MASK_DERIVEDMESH,
+ CD_CALLOC, numLoops);
+ CustomData_copy(&source->polyData, &dm->polyData, CD_MASK_DERIVEDMESH,
+ CD_CALLOC, numPolys);
dm->type = type;
dm->numVertData = numVerts;
dm->numEdgeData = numEdges;
- dm->numFaceData = numFaces;
+ dm->numTessFaceData = numTessFaces;
+ dm->numLoopData = numLoops;
+ dm->numPolyData = numPolys;
DM_init_funcs(dm);
@@ -214,63 +313,152 @@ int DM_release(DerivedMesh *dm)
GPU_drawobject_free( dm );
CustomData_free(&dm->vertData, dm->numVertData);
CustomData_free(&dm->edgeData, dm->numEdgeData);
- CustomData_free(&dm->faceData, dm->numFaceData);
+ CustomData_free(&dm->faceData, dm->numTessFaceData);
+ CustomData_free(&dm->loopData, dm->numLoopData);
+ CustomData_free(&dm->polyData, dm->numPolyData);
return 1;
}
else {
CustomData_free_temporary(&dm->vertData, dm->numVertData);
CustomData_free_temporary(&dm->edgeData, dm->numEdgeData);
- CustomData_free_temporary(&dm->faceData, dm->numFaceData);
+ CustomData_free_temporary(&dm->faceData, dm->numTessFaceData);
+ CustomData_free_temporary(&dm->loopData, dm->numLoopData);
+ CustomData_free_temporary(&dm->polyData, dm->numPolyData);
return 0;
}
}
-void DM_to_mesh(DerivedMesh *dm, Mesh *me)
+void DM_DupPolys(DerivedMesh *source, DerivedMesh *target)
+{
+ CustomData_free(&target->loopData, source->numLoopData);
+ CustomData_free(&target->polyData, source->numPolyData);
+
+ CustomData_copy(&source->loopData, &target->loopData, CD_MASK_DERIVEDMESH, CD_DUPLICATE, source->numLoopData);
+ CustomData_copy(&source->polyData, &target->polyData, CD_MASK_DERIVEDMESH, CD_DUPLICATE, source->numPolyData);
+
+ target->numLoopData = source->numLoopData;
+ target->numPolyData = source->numPolyData;
+
+ if (!CustomData_has_layer(&target->polyData, CD_MPOLY)) {
+ MPoly *mpoly;
+ MLoop *mloop;
+
+ mloop = source->dupLoopArray(source);
+ mpoly = source->dupPolyArray(source);
+ CustomData_add_layer(&target->loopData, CD_MLOOP, CD_ASSIGN, mloop, source->numLoopData);
+ CustomData_add_layer(&target->polyData, CD_MPOLY, CD_ASSIGN, mpoly, source->numPolyData);
+ }
+}
+
+/* note: until all modifiers can take MPoly's as input,
+ * use this at the start of modifiers */
+void DM_ensure_tessface(DerivedMesh *dm)
+{
+ const int numTessFaces = dm->getNumTessFaces(dm);
+ const int numPolys = dm->getNumPolys(dm);
+
+ if ( (numTessFaces == 0) && (numPolys != 0)) {
+ dm->recalcTesselation(dm);
+
+ if (dm->getNumTessFaces(dm) != 0) {
+ /* printf("info %s: polys -> ngons calculated\n", __func__); */
+ }
+ else {
+ printf("warning %s: could not create tessfaces from %d polygons, dm->type=%d\n",
+ __func__, numPolys, dm->type);
+ }
+ }
+}
+
+void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob)
{
/* dm might depend on me, so we need to do everything with a local copy */
Mesh tmp = *me;
- int totvert, totedge, totface;
-
+ int totvert, totedge /*, totface */ /* UNUSED */, totloop, totpoly;
+ int did_shapekeys=0;
+
memset(&tmp.vdata, 0, sizeof(tmp.vdata));
memset(&tmp.edata, 0, sizeof(tmp.edata));
memset(&tmp.fdata, 0, sizeof(tmp.fdata));
+ memset(&tmp.ldata, 0, sizeof(tmp.ldata));
+ memset(&tmp.pdata, 0, sizeof(tmp.pdata));
totvert = tmp.totvert = dm->getNumVerts(dm);
totedge = tmp.totedge = dm->getNumEdges(dm);
- totface = tmp.totface = dm->getNumFaces(dm);
+ totloop = tmp.totloop = dm->getNumLoops(dm);
+ totpoly = tmp.totpoly = dm->getNumPolys(dm);
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);
+ CustomData_copy(&dm->loopData, &tmp.ldata, CD_MASK_MESH, CD_DUPLICATE, totloop);
+ CustomData_copy(&dm->polyData, &tmp.pdata, CD_MASK_MESH, CD_DUPLICATE, totpoly);
+
+ if (CustomData_has_layer(&dm->vertData, CD_SHAPEKEY)) {
+ KeyBlock *kb;
+ int uid;
+
+ if (ob) {
+ kb = BLI_findlink(&me->key->block, ob->shapenr-1);
+ if (kb) {
+ uid = kb->uid;
+ }
+ else {
+ printf("%s: error - could not find active shapekey %d!\n",
+ __func__, ob->shapenr-1);
+ uid = INT_MAX;
+ }
+ }
+ else {
+ /*if no object, set to INT_MAX so we don't mess up any shapekey layers*/
+ uid = INT_MAX;
+ }
+
+ shapekey_layers_to_keyblocks(dm, me, uid);
+ did_shapekeys = 1;
+ }
+
/* 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, CD_ASSIGN, dm->dupVertArray(dm), totvert);
if(!CustomData_has_layer(&tmp.edata, CD_MEDGE))
CustomData_add_layer(&tmp.edata, CD_MEDGE, CD_ASSIGN, dm->dupEdgeArray(dm), totedge);
- if(!CustomData_has_layer(&tmp.fdata, CD_MFACE))
- CustomData_add_layer(&tmp.fdata, CD_MFACE, CD_ASSIGN, dm->dupFaceArray(dm), totface);
+ if(!CustomData_has_layer(&tmp.pdata, CD_MPOLY)) {
+ tmp.mloop = dm->dupLoopArray(dm);
+ tmp.mpoly = dm->dupPolyArray(dm);
+
+ CustomData_add_layer(&tmp.ldata, CD_MLOOP, CD_ASSIGN, tmp.mloop, tmp.totloop);
+ CustomData_add_layer(&tmp.pdata, CD_MPOLY, CD_ASSIGN, tmp.mpoly, tmp.totpoly);
+ }
/* object had got displacement layer, should copy this layer to save sculpted data */
/* NOTE: maybe some other layers should be copied? nazgul */
- if(CustomData_has_layer(&me->fdata, CD_MDISPS)) {
- if (totface == me->totface) {
- MDisps *mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS);
- CustomData_add_layer(&tmp.fdata, CD_MDISPS, CD_DUPLICATE, mdisps, totface);
+ if(CustomData_has_layer(&me->ldata, CD_MDISPS)) {
+ if (totloop == me->totloop) {
+ MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
+ CustomData_add_layer(&tmp.ldata, CD_MDISPS, CD_DUPLICATE, mdisps, totloop);
}
}
- mesh_update_customdata_pointers(&tmp);
+ /* yes, must be before _and_ after tesselate */
+ mesh_update_customdata_pointers(&tmp, TRUE);
+
+ BKE_mesh_tessface_calc(&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) {
+ CustomData_free(&me->ldata, me->totloop);
+ CustomData_free(&me->pdata, me->totpoly);
+
+ /* ok, this should now use new CD shapekey data,
+ which shouuld be fed through the modifier
+ stack*/
+ if(tmp.totvert != me->totvert && !did_shapekeys && me->key) {
+ printf("YEEK! this should be recoded! Shape key loss!!!\n");
if(tmp.key) tmp.key->id.us--;
tmp.key = NULL;
}
@@ -315,9 +503,19 @@ void DM_add_edge_layer(DerivedMesh *dm, int type, int alloctype, void *layer)
CustomData_add_layer(&dm->edgeData, type, alloctype, layer, dm->numEdgeData);
}
-void DM_add_face_layer(DerivedMesh *dm, int type, int alloctype, void *layer)
+void DM_add_tessface_layer(DerivedMesh *dm, int type, int alloctype, void *layer)
+{
+ CustomData_add_layer(&dm->faceData, type, alloctype, layer, dm->numTessFaceData);
+}
+
+void DM_add_loop_layer(DerivedMesh *dm, int type, int alloctype, void *layer)
{
- CustomData_add_layer(&dm->faceData, type, alloctype, layer, dm->numFaceData);
+ CustomData_add_layer(&dm->loopData, type, alloctype, layer, dm->numLoopData);
+}
+
+void DM_add_poly_layer(DerivedMesh *dm, int type, int alloctype, void *layer)
+{
+ CustomData_add_layer(&dm->polyData, type, alloctype, layer, dm->numPolyData);
}
void *DM_get_vert_data(DerivedMesh *dm, int index, int type)
@@ -330,7 +528,7 @@ void *DM_get_edge_data(DerivedMesh *dm, int index, int type)
return CustomData_get(&dm->edgeData, index, type);
}
-void *DM_get_face_data(DerivedMesh *dm, int index, int type)
+void *DM_get_tessface_data(DerivedMesh *dm, int index, int type)
{
return CustomData_get(&dm->faceData, index, type);
}
@@ -351,14 +549,24 @@ void *DM_get_edge_data_layer(DerivedMesh *dm, int type)
return CustomData_get_layer(&dm->edgeData, type);
}
-void *DM_get_face_data_layer(DerivedMesh *dm, int type)
+void *DM_get_tessface_data_layer(DerivedMesh *dm, int type)
{
- if(type == CD_MFACE)
- return dm->getFaceArray(dm);
+ if (type == CD_MFACE)
+ return dm->getTessFaceArray(dm);
return CustomData_get_layer(&dm->faceData, type);
}
+void *DM_get_poly_data_layer(DerivedMesh *dm, int type)
+{
+ return CustomData_get_layer(&dm->polyData, type);
+}
+
+void *DM_get_loop_data_layer(DerivedMesh *dm, int type)
+{
+ return CustomData_get_layer(&dm->loopData, type);
+}
+
void DM_set_vert_data(DerivedMesh *dm, int index, int type, void *data)
{
CustomData_set(&dm->vertData, index, type, data);
@@ -369,7 +577,7 @@ void DM_set_edge_data(DerivedMesh *dm, int index, int type, void *data)
CustomData_set(&dm->edgeData, index, type, data);
}
-void DM_set_face_data(DerivedMesh *dm, int index, int type, void *data)
+void DM_set_tessface_data(DerivedMesh *dm, int index, int type, void *data)
{
CustomData_set(&dm->faceData, index, type, data);
}
@@ -388,13 +596,27 @@ void DM_copy_edge_data(DerivedMesh *source, DerivedMesh *dest,
source_index, dest_index, count);
}
-void DM_copy_face_data(DerivedMesh *source, DerivedMesh *dest,
+void DM_copy_tessface_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);
}
+void DM_copy_loop_data(DerivedMesh *source, DerivedMesh *dest,
+ int source_index, int dest_index, int count)
+{
+ CustomData_copy_data(&source->loopData, &dest->loopData,
+ source_index, dest_index, count);
+}
+
+void DM_copy_poly_data(DerivedMesh *source, DerivedMesh *dest,
+ int source_index, int dest_index, int count)
+{
+ CustomData_copy_data(&source->polyData, &dest->polyData,
+ source_index, dest_index, count);
+}
+
void DM_free_vert_data(struct DerivedMesh *dm, int index, int count)
{
CustomData_free_elem(&dm->vertData, index, count);
@@ -405,11 +627,21 @@ void DM_free_edge_data(struct DerivedMesh *dm, int index, int count)
CustomData_free_elem(&dm->edgeData, index, count);
}
-void DM_free_face_data(struct DerivedMesh *dm, int index, int count)
+void DM_free_tessface_data(struct DerivedMesh *dm, int index, int count)
{
CustomData_free_elem(&dm->faceData, index, count);
}
+void DM_free_loop_data(struct DerivedMesh *dm, int index, int count)
+{
+ CustomData_free_elem(&dm->loopData, index, count);
+}
+
+void DM_free_poly_data(struct DerivedMesh *dm, int index, int count)
+{
+ CustomData_free_elem(&dm->polyData, index, count);
+}
+
void DM_interp_vert_data(DerivedMesh *source, DerivedMesh *dest,
int *src_indices, float *weights,
int count, int dest_index)
@@ -427,7 +659,7 @@ void DM_interp_edge_data(DerivedMesh *source, DerivedMesh *dest,
weights, (float*)vert_weights, count, dest_index);
}
-void DM_interp_face_data(DerivedMesh *source, DerivedMesh *dest,
+void DM_interp_tessface_data(DerivedMesh *source, DerivedMesh *dest,
int *src_indices,
float *weights, FaceVertWeight *vert_weights,
int count, int dest_index)
@@ -436,13 +668,28 @@ void DM_interp_face_data(DerivedMesh *source, DerivedMesh *dest,
weights, (float*)vert_weights, count, dest_index);
}
-void DM_swap_face_data(DerivedMesh *dm, int index, const int *corner_indices)
+void DM_swap_tessface_data(DerivedMesh *dm, int index, const int *corner_indices)
{
CustomData_swap(&dm->faceData, index, corner_indices);
}
-///
+void DM_interp_loop_data(DerivedMesh *source, DerivedMesh *dest,
+ int *src_indices,
+ float *weights, int count, int dest_index)
+{
+ CustomData_interp(&source->loopData, &dest->loopData, src_indices,
+ weights, NULL, count, dest_index);
+}
+void DM_interp_poly_data(DerivedMesh *source, DerivedMesh *dest,
+ int *src_indices,
+ float *weights, int count, int dest_index)
+{
+ CustomData_interp(&source->polyData, &dest->polyData, src_indices,
+ weights, NULL, count, dest_index);
+}
+
+///
DerivedMesh *mesh_create_derived(Mesh *me, Object *ob, float (*vertCos)[3])
{
DerivedMesh *dm = CDDM_from_mesh(me, ob);
@@ -458,17 +705,25 @@ DerivedMesh *mesh_create_derived(Mesh *me, Object *ob, float (*vertCos)[3])
return dm;
}
-DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, ModifierData *md)
+/***/
+
+DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob,
+ ModifierData *md, int build_shapekey_layers)
{
Mesh *me = ob->data;
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
DerivedMesh *dm;
+ KeyBlock *kb;
md->scene= scene;
if (!(md->mode&eModifierMode_Realtime)) return NULL;
if (mti->isDisabled && mti->isDisabled(md, 0)) return NULL;
-
+
+ if (build_shapekey_layers && me->key && (kb = BLI_findlink(&me->key->block, ob->shapenr-1))) {
+ key_to_mesh(kb, me);
+ }
+
if (mti->type==eModifierTypeType_OnlyDeform) {
int numVerts;
float (*deformedVerts)[3] = mesh_getVertexCos(me, &numVerts);
@@ -476,9 +731,16 @@ DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, Modifier
mti->deformVerts(md, ob, NULL, deformedVerts, numVerts, 0, 0);
dm = mesh_create_derived(me, ob, deformedVerts);
+ if (build_shapekey_layers)
+ add_shapekey_layers(dm, me, ob);
+
MEM_freeN(deformedVerts);
} else {
DerivedMesh *tdm = mesh_create_derived(me, ob, NULL);
+
+ if (build_shapekey_layers)
+ add_shapekey_layers(tdm, me, ob);
+
dm = mti->applyModifier(md, ob, tdm, 0, 0);
if(tdm != dm) tdm->release(tdm);
@@ -487,22 +749,22 @@ DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, Modifier
return dm;
}
-static float *get_editmesh_orco_verts(EditMesh *em)
+static float *get_editbmesh_orco_verts(BMEditMesh *em)
{
- EditVert *eve;
+ BMIter iter;
+ BMVert *eve;
float *orco;
int a, totvert;
/* these may not really be the orco's, but it's only for preview.
* could be solver better once, but isn't simple */
- totvert= 0;
- for(eve=em->verts.first; eve; eve=eve->next)
- totvert++;
+ totvert= em->bm->totvert;
orco = MEM_mallocN(sizeof(float)*3*totvert, "EditMesh Orco");
- for(a=0, eve=em->verts.first; eve; eve=eve->next, a+=3) {
+ eve = BM_iter_new(&iter, em->bm, BM_VERTS_OF_MESH, NULL);
+ for (a=0; eve; eve=BM_iter_step(&iter), a+=3) {
copy_v3_v3(orco+a, eve->co);
}
@@ -510,8 +772,7 @@ static float *get_editmesh_orco_verts(EditMesh *em)
}
/* orco custom data layer */
-
-static void *get_orco_coords_dm(Object *ob, EditMesh *em, int layer, int *free)
+static void *get_orco_coords_dm(Object *ob, BMEditMesh *em, int layer, int *free)
{
*free= 0;
@@ -520,7 +781,7 @@ static void *get_orco_coords_dm(Object *ob, EditMesh *em, int layer, int *free)
*free= 1;
if(em)
- return (float(*)[3])get_editmesh_orco_verts(em);
+ return (float(*)[3])get_editbmesh_orco_verts(em);
else
return (float(*)[3])get_mesh_orco_verts(ob);
}
@@ -541,13 +802,13 @@ static void *get_orco_coords_dm(Object *ob, EditMesh *em, int layer, int *free)
return NULL;
}
-static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, EditMesh *em, int layer)
+static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, BMEditMesh *em, int layer)
{
DerivedMesh *dm;
float (*orco)[3];
int free;
- if(em) dm= CDDM_from_editmesh(em, me);
+ if(em) dm= CDDM_from_BMEditMesh(em, me, FALSE, FALSE);
else dm= CDDM_from_mesh(me, ob);
orco= get_orco_coords_dm(ob, em, layer, &free);
@@ -562,7 +823,8 @@ static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, EditMesh *em, int layer
return dm;
}
-static void add_orco_dm(Object *ob, EditMesh *em, DerivedMesh *dm, DerivedMesh *orcodm, int layer)
+static void add_orco_dm(Object *ob, BMEditMesh *em, DerivedMesh *dm,
+ DerivedMesh *orcodm, int layer)
{
float (*orco)[3], (*layerorco)[3];
int totvert, free;
@@ -775,19 +1037,35 @@ void DM_update_weight_mcol(Object *ob, DerivedMesh *dm, int const draw_flag,
{
ColorBand *coba= stored_cb; /* warning, not a local var */
- MFace *mf = dm->getFaceArray(dm);
- int numFaces = dm->getNumFaces(dm);
- int numVerts = dm->getNumVerts(dm);
unsigned char *wtcol_v;
- unsigned char *wtcol_f = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
- int i;
+#if 0 /* See coment below. */
+ unsigned char *wtcol_f = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
+#endif
+ unsigned char(*wtcol_l)[4] = CustomData_get_layer(dm->getLoopDataLayout(dm), CD_WEIGHT_MLOOPCOL);
+#if 0 /* See coment below. */
+ MFace *mf = dm->getTessFaceArray(dm);
+#endif
+ MLoop *mloop = dm->getLoopArray(dm), *ml;
+ MPoly *mp = dm->getPolyArray(dm);
+ int numFaces = dm->getNumTessFaces(dm);
+ int numVerts = dm->getNumVerts(dm);
+ int totloop;
+ int i, j;
+#if 0 /* See comment below */
/* If no CD_WEIGHT_MCOL existed yet, add a new one! */
if (!wtcol_f)
wtcol_f = CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_CALLOC, NULL, numFaces);
if (wtcol_f) {
unsigned char *wtcol_f_step = wtcol_f;
+# else
+ /* XXX We have to create a CD_WEIGHT_MCOL, else it might sigsev (after a SubSurf mod, eg)... */
+ if(!dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL))
+ CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_CALLOC, NULL, numFaces);
+
+ {
+#endif
/* Weights are given by caller. */
if (weights) {
@@ -813,7 +1091,13 @@ void DM_update_weight_mcol(Object *ob, DerivedMesh *dm, int const draw_flag,
wtcol_v = calc_weightpaint_vert_array(ob, dm, draw_flag, coba);
/* Now copy colors in all face verts. */
+ /*first add colors to the tesselation faces*/
+ /* XXX Why update that layer? We have to update WEIGHT_MLOOPCOL anyway,
+ * and tesselation recreates mface layers from mloop/mpoly ones, so no
+ * need to fill WEIGHT_MCOL here. */
+#if 0
for (i = 0; i < numFaces; i++, mf++, wtcol_f_step += (4 * 4)) {
+ /*origindex being NULL means we're operating on original mesh data*/
#if 0
unsigned int fidx= mf->v4 ? 3:2;
@@ -830,13 +1114,137 @@ void DM_update_weight_mcol(Object *ob, DerivedMesh *dm, int const draw_flag,
do {
copy_v4_v4_char((char *)&wtcol_f_step[fidx * 4],
- (char *)&wtcol_v[4 * (*(&mf->v1 + fidx))]);
+ (char *)&wtcol_v[4 * (*(&mf->v1 + fidx))]);
} while (fidx--);
}
+#endif
+ /*now add to loops, so the data can be passed through the modifier stack*/
+ /* If no CD_WEIGHT_MLOOPCOL existed yet, we have to add a new one! */
+ if (!wtcol_l) {
+ BLI_array_declare(wtcol_l);
+ totloop = 0;
+ for (i=0; i<dm->numPolyData; i++, mp++) {
+ ml = mloop + mp->loopstart;
+
+ BLI_array_growitems(wtcol_l, mp->totloop);
+ for (j = 0; j < mp->totloop; j++, ml++, totloop++) {
+ copy_v4_v4_char((char *)&wtcol_l[totloop],
+ (char *)&wtcol_v[4 * ml->v]);
+ }
+ }
+ CustomData_add_layer(&dm->loopData, CD_WEIGHT_MLOOPCOL, CD_ASSIGN, wtcol_l, totloop);
+ }
+ else {
+ totloop = 0;
+ for (i=0; i < dm->numPolyData; i++, mp++) {
+ ml = mloop + mp->loopstart;
+
+ for (j=0; j < mp->totloop; j++, ml++, totloop++) {
+ copy_v4_v4_char((char *)&wtcol_l[totloop],
+ (char *)&wtcol_v[4 * ml->v]);
+ }
+ }
+ }
MEM_freeN(wtcol_v);
}
}
+
+static void shapekey_layers_to_keyblocks(DerivedMesh *dm, Mesh *me, int actshape_uid)
+{
+ KeyBlock *kb;
+ int i, j, tot;
+
+ if (!me->key)
+ return;
+
+ tot = CustomData_number_of_layers(&dm->vertData, CD_SHAPEKEY);
+ for (i=0; i<tot; i++) {
+ CustomDataLayer *layer = &dm->vertData.layers[CustomData_get_layer_index_n(&dm->vertData, CD_SHAPEKEY, i)];
+ float (*cos)[3], (*kbcos)[3];
+
+ for (kb=me->key->block.first; kb; kb=kb->next) {
+ if (kb->uid == layer->uid)
+ break;
+ }
+
+ if (!kb) {
+ kb = add_keyblock(me->key, layer->name);
+ kb->uid = layer->uid;
+ }
+
+ if (kb->data)
+ MEM_freeN(kb->data);
+
+ cos = CustomData_get_layer_n(&dm->vertData, CD_SHAPEKEY, i);
+ kb->totelem = dm->numVertData;
+
+ kb->data = kbcos = MEM_mallocN(sizeof(float)*3*kb->totelem, "kbcos DerivedMesh.c");
+ if (kb->uid == actshape_uid) {
+ MVert *mvert = dm->getVertArray(dm);
+
+ for (j=0; j<dm->numVertData; j++, kbcos++, mvert++) {
+ copy_v3_v3(*kbcos, mvert->co);
+ }
+ } else {
+ for (j=0; j<kb->totelem; j++, cos++, kbcos++) {
+ copy_v3_v3(*kbcos, *cos);
+ }
+ }
+ }
+
+ for (kb=me->key->block.first; kb; kb=kb->next) {
+ if (kb->totelem != dm->numVertData) {
+ if (kb->data)
+ MEM_freeN(kb->data);
+
+ kb->totelem = dm->numVertData;
+ kb->data = MEM_callocN(sizeof(float)*3*kb->totelem, "kb->data derivedmesh.c");
+ fprintf(stderr, "%s: lost a shapekey layer! (bmesh internal error)\n", __func__);
+ }
+ }
+}
+
+static void add_shapekey_layers(DerivedMesh *dm, Mesh *me, Object *UNUSED(ob))
+{
+ KeyBlock *kb;
+ Key *key = me->key;
+ int i;
+ const size_t shape_alloc_len = sizeof(float) * 3 * me->totvert;
+
+ if (!me->key)
+ return;
+
+ /* ensure we can use mesh vertex count for derived mesh custom data */
+ if (me->totvert != dm->getNumVerts(dm)) {
+ fprintf(stderr,
+ "%s: vertex size mismatch (mesh/dm) '%s' (%d != %d)\n",
+ __func__, me->id.name+2, me->totvert, dm->getNumVerts(dm));
+ return;
+ }
+
+ for (i=0, kb=key->block.first; kb; kb=kb->next, i++) {
+ int ci;
+ float *array;
+
+ if (me->totvert != kb->totelem) {
+ fprintf(stderr,
+ "%s: vertex size mismatch (mesh/keyblock) '%s' (%d != %d)\n",
+ __func__, me->id.name+2, me->totvert, kb->totelem);
+ array = MEM_callocN(shape_alloc_len, __func__);
+ }
+ else {
+ array = MEM_mallocN(shape_alloc_len, __func__);
+ memcpy(array, kb->data, shape_alloc_len);
+ }
+
+ CustomData_add_layer_named(&dm->vertData, CD_SHAPEKEY, CD_ASSIGN, array, dm->numVertData, kb->name);
+ ci = CustomData_get_layer_index_n(&dm->vertData, CD_SHAPEKEY, i);
+
+ dm->vertData.layers[ci].uid = kb->uid;
+ }
+}
+
/* new value for useDeform -1 (hack for the gameengine):
* - apply only the modifier stack of the object, skipping the virtual modifiers,
* - don't apply the key
@@ -845,14 +1253,15 @@ void DM_update_weight_mcol(Object *ob, DerivedMesh *dm, int const draw_flag,
static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos)[3],
DerivedMesh **deform_r, DerivedMesh **final_r,
int useRenderParams, int useDeform,
- int needMapping, CustomDataMask dataMask, int index, int useCache)
+ int needMapping, CustomDataMask dataMask,
+ int index, int useCache, int build_shapekey_layers)
{
Mesh *me = ob->data;
ModifierData *firstmd, *md, *previewmd = NULL;
LinkNode *datamasks, *curr;
CustomDataMask mask, nextmask, append_mask = 0;
float (*deformedVerts)[3] = NULL;
- DerivedMesh *dm, *orcodm, *clothorcodm, *finaldm;
+ DerivedMesh *dm=NULL, *orcodm, *clothorcodm, *finaldm;
int numVerts = me->totvert;
int required_mode;
int isPrevDeform= FALSE;
@@ -940,7 +1349,10 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
*/
if (deform_r) {
*deform_r = CDDM_from_mesh(me, ob);
-
+
+ if (build_shapekey_layers)
+ add_shapekey_layers(dm, me, ob);
+
if(deformedVerts) {
CDDM_apply_vert_coords(*deform_r, deformedVerts);
CDDM_calc_normals(*deform_r);
@@ -1054,6 +1466,9 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
} else {
dm = CDDM_from_mesh(me, ob);
+ if (build_shapekey_layers)
+ add_shapekey_layers(dm, me, ob);
+
if(deformedVerts) {
CDDM_apply_vert_coords(dm, deformedVerts);
CDDM_calc_normals(dm);
@@ -1073,11 +1488,11 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
/* calc */
DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
- DM_add_face_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
+ DM_add_poly_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
range_vn_i(DM_get_vert_data_layer(dm, CD_ORIGINDEX), dm->numVertData, 0);
range_vn_i(DM_get_edge_data_layer(dm, CD_ORIGINDEX), dm->numEdgeData, 0);
- range_vn_i(DM_get_face_data_layer(dm, CD_ORIGINDEX), dm->numFaceData, 0);
+ range_vn_i(DM_get_poly_data_layer(dm, CD_ORIGINDEX), dm->numPolyData, 0);
}
}
@@ -1094,9 +1509,12 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
add_orco_dm(ob, NULL, dm, clothorcodm, CD_CLOTH_ORCO);
/* add an origspace layer if needed */
- if(((CustomDataMask)GET_INT_FROM_POINTER(curr->link)) & CD_MASK_ORIGSPACE)
- if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE))
- DM_add_face_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL);
+ if(((CustomDataMask)GET_INT_FROM_POINTER(curr->link)) & CD_MASK_ORIGSPACE_MLOOP) {
+ if(!CustomData_has_layer(&dm->loopData, CD_ORIGSPACE_MLOOP)) {
+ DM_add_loop_layer(dm, CD_ORIGSPACE_MLOOP, CD_CALLOC, NULL);
+ DM_init_origspace(dm);
+ }
+ }
ndm = mti->applyModifier(md, ob, dm, useRenderParams, useCache);
@@ -1196,10 +1614,21 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
DM_update_weight_mcol(ob, finaldm, draw_flag, NULL, 0, NULL);
#endif
} else {
- finaldm = CDDM_from_mesh(me, ob);
+ int recalc_normals= 0;
+ finaldm = CDDM_from_mesh(me, ob);
+
+ if(build_shapekey_layers) {
+ add_shapekey_layers(finaldm, me, ob);
+ recalc_normals= 1;
+ }
+
if(deformedVerts) {
CDDM_apply_vert_coords(finaldm, deformedVerts);
+ recalc_normals= 1;
+ }
+
+ if(recalc_normals) {
CDDM_calc_normals(finaldm);
}
@@ -1228,6 +1657,36 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
}
#endif /* WITH_GAMEENGINE */
+ {
+ /* calculating normals can re-calculate tessfaces in some cases */
+ int num_tessface = finaldm->getNumTessFaces(finaldm);
+ /* --------------------------------------------------------------------- */
+ /* First calculate the polygon and vertex normals, re-tesselation
+ * copies these into the tessface's normal layer */
+
+
+ /* comment because this causes a bug when deform is applied after a
+ * bug when applied after a subsurf modifier (SubSurf -> Cast) for eg,
+ * it also looks like this isn't even needed since code above recalc's
+ * normals - campbell */
+#if 0
+ finaldm->calcNormals(finaldm);
+#endif
+
+ /* Re-tesselation is necessary to push render data (uvs, textures, colors)
+ * from loops and polys onto the tessfaces. This may be currently be
+ * redundantin cases where the render mode doesn't use these inputs, but
+ * ideally eventually tesselation would happen on-demand, and this is one
+ * of the primary places it would be needed. */
+ if (num_tessface == 0 && finaldm->getNumTessFaces(finaldm) == 0) {
+ finaldm->recalcTesselation(finaldm);
+ }
+ /* Need to watch this, it can cause issues, see bug [#29338] */
+ /* take care with this block, we really need testing frameworks */
+ /* --------------------------------------------------------------------- */
+ }
+
+
*final_r = finaldm;
if(orcodm)
@@ -1241,21 +1700,24 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
BLI_linklist_free(datamasks, NULL);
}
-float (*editmesh_get_vertex_cos(EditMesh *em, int *numVerts_r))[3]
+float (*editbmesh_get_vertex_cos(BMEditMesh *em, int *numVerts_r))[3]
{
- int i, numVerts = *numVerts_r = BLI_countlist(&em->verts);
+ int i, numVerts = *numVerts_r = em->bm->totvert;
float (*cos)[3];
- EditVert *eve;
+ BMIter iter;
+ BMVert *eve;
+
+ cos = MEM_mallocN(sizeof(float)*3*numVerts, "vertexcos");
- cos = MEM_mallocN(sizeof(*cos)*numVerts, "vertexcos");
- for (i=0,eve=em->verts.first; i<numVerts; i++,eve=eve->next) {
+ eve = BM_iter_new(&iter, em->bm, BM_VERTS_OF_MESH, NULL);
+ for (i=0; eve; eve=BM_iter_step(&iter), i++) {
copy_v3_v3(cos[i], eve->co);
}
return cos;
}
-int editmesh_modifier_is_enabled(Scene *scene, ModifierData *md, DerivedMesh *dm)
+int editbmesh_modifier_is_enabled(Scene *scene, ModifierData *md, DerivedMesh *dm)
{
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
@@ -1269,7 +1731,7 @@ int editmesh_modifier_is_enabled(Scene *scene, ModifierData *md, DerivedMesh *dm
return 1;
}
-static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, DerivedMesh **cage_r,
+static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, DerivedMesh **cage_r,
DerivedMesh **final_r,
CustomDataMask dataMask)
{
@@ -1284,7 +1746,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
modifiers_clearErrors(ob);
if(cage_r && cageIndex == -1) {
- *cage_r = editmesh_get_derived(em, NULL);
+ *cage_r = getEditDerivedBMesh(em, ob, NULL);
}
dm = NULL;
@@ -1298,7 +1760,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
md->scene= scene;
- if(!editmesh_modifier_is_enabled(scene, md, dm))
+ if(!editbmesh_modifier_is_enabled(scene, md, dm))
continue;
/* add an orco layer if needed by this modifier */
@@ -1326,7 +1788,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
MEM_mallocN(sizeof(*deformedVerts) * numVerts, "dfmv");
dm->getVertCos(dm, deformedVerts);
} else {
- deformedVerts = editmesh_get_vertex_cos(em, &numVerts);
+ deformedVerts = editbmesh_get_vertex_cos(em, &numVerts);
}
}
@@ -1352,7 +1814,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
}
} else {
- dm = CDDM_from_editmesh(em, ob->data);
+ dm = CDDM_from_BMEditMesh(em, ob->data, FALSE, FALSE);
if(deformedVerts) {
CDDM_apply_vert_coords(dm, deformedVerts);
@@ -1386,9 +1848,12 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
DM_set_only_copy(dm, mask | CD_MASK_ORIGINDEX);
- if(mask & CD_MASK_ORIGSPACE)
- if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE))
- DM_add_face_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL);
+ if(mask & CD_MASK_ORIGSPACE_MLOOP) {
+ if(!CustomData_has_layer(&dm->loopData, CD_ORIGSPACE_MLOOP)) {
+ DM_add_loop_layer(dm, CD_ORIGSPACE_MLOOP, CD_CALLOC, NULL);
+ DM_init_origspace(dm);
+ }
+ }
if (mti->applyModifierEM)
ndm = mti->applyModifierEM(md, ob, em, dm);
@@ -1416,7 +1881,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
*cage_r = dm;
} else {
*cage_r =
- editmesh_get_derived(em,
+ getEditDerivedBMesh(em, ob,
deformedVerts ? MEM_dupallocN(deformedVerts) : NULL);
}
}
@@ -1434,16 +1899,26 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
if(!(cage_r && dm == *cage_r)) dm->release(dm);
CDDM_apply_vert_coords(*final_r, deformedVerts);
- CDDM_calc_normals(*final_r);
+ CDDM_calc_normals(*final_r); /* was CDDM_calc_normals_mapping - campbell */
} else if (dm) {
*final_r = dm;
+ (*final_r)->calcNormals(*final_r); /* BMESH_ONLY - BMESH_TODO. check if this is needed */
} else if (!deformedVerts && cage_r && *cage_r) {
*final_r = *cage_r;
+ (*final_r)->calcNormals(*final_r); /* BMESH_ONLY - BMESH_TODO. check if this is needed */
} else {
- *final_r = editmesh_get_derived(em, deformedVerts);
+ *final_r = getEditDerivedBMesh(em, ob, deformedVerts);
deformedVerts = NULL;
+ (*final_r)->calcNormals(*final_r); /* BMESH_ONLY - BMESH_TODO. check if this is needed */
}
+ /* --- */
+ /* BMESH_ONLY, ensure tessface's used for drawing,
+ * but dont recalculate if the last modifier in the stack gives us tessfaces */
+ DM_ensure_tessface(*final_r);
+ if (cage_r && (*cage_r != *final_r)) DM_ensure_tessface(*cage_r);
+ /* --- */
+
/* add an orco layer if needed */
if(dataMask & CD_MASK_ORCO)
add_orco_dm(ob, em, *final_r, orcodm, CD_ORCO);
@@ -1487,18 +1962,19 @@ static void clear_mesh_caches(Object *ob)
}
}
-static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask)
+static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask,
+ int build_shapekey_layers)
{
Object *obact = scene->basact?scene->basact->object:NULL;
- int editing = paint_facesel_test(ob) || paint_vertsel_test(ob);/* paint_vertsel_test */
+ int editing = paint_facesel_test(ob);
/* weight paint and face select need original indices because of selection buffer drawing */
- int needMapping = (ob==obact) && (editing || (ob->mode & (OB_MODE_WEIGHT_PAINT|OB_MODE_VERTEX_PAINT)));
+ int needMapping = (ob==obact) && (editing || (ob->mode & (OB_MODE_WEIGHT_PAINT|OB_MODE_VERTEX_PAINT|OB_MODE_TEXTURE_PAINT)));
clear_mesh_caches(ob);
mesh_calc_modifiers(scene, ob, NULL, &ob->derivedDeform,
&ob->derivedFinal, 0, 1,
- needMapping, dataMask, -1, 1);
+ needMapping, dataMask, -1, 1, build_shapekey_layers);
DM_set_object_boundbox (ob, ob->derivedFinal);
@@ -1507,7 +1983,7 @@ static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask)
ob->lastDataMask = dataMask;
}
-static void editmesh_build_data(Scene *scene, Object *obedit, EditMesh *em, CustomDataMask dataMask)
+static void editbmesh_build_data(Scene *scene, Object *obedit, BMEditMesh *em, CustomDataMask dataMask)
{
clear_mesh_caches(obedit);
@@ -1524,7 +2000,7 @@ static void editmesh_build_data(Scene *scene, Object *obedit, EditMesh *em, Cust
em->derivedCage = NULL;
}
- editmesh_calc_modifiers(scene, obedit, em, &em->derivedCage, &em->derivedFinal, dataMask);
+ editbmesh_calc_modifiers(scene, obedit, em, &em->derivedCage, &em->derivedFinal, dataMask);
DM_set_object_boundbox (obedit, em->derivedFinal);
em->lastDataMask = dataMask;
@@ -1532,12 +2008,13 @@ static void editmesh_build_data(Scene *scene, Object *obedit, EditMesh *em, Cust
em->derivedCage->needsFree = 0;
}
-void makeDerivedMesh(Scene *scene, Object *ob, EditMesh *em, CustomDataMask dataMask)
+void makeDerivedMesh(Scene *scene, Object *ob, BMEditMesh *em,
+ CustomDataMask dataMask, int build_shapekey_layers)
{
if (em) {
- editmesh_build_data(scene, ob, em, dataMask);
+ editbmesh_build_data(scene, ob, em, dataMask);
} else {
- mesh_build_data(scene, ob, dataMask);
+ mesh_build_data(scene, ob, dataMask, build_shapekey_layers);
}
}
@@ -1549,7 +2026,7 @@ DerivedMesh *mesh_get_derived_final(Scene *scene, Object *ob, CustomDataMask dat
* the data we need, rebuild the derived mesh
*/
if(!ob->derivedFinal || (dataMask & ob->lastDataMask) != dataMask)
- mesh_build_data(scene, ob, dataMask);
+ mesh_build_data(scene, ob, dataMask, 0);
return ob->derivedFinal;
}
@@ -1560,7 +2037,7 @@ DerivedMesh *mesh_get_derived_deform(Scene *scene, Object *ob, CustomDataMask da
* the data we need, rebuild the derived mesh
*/
if(!ob->derivedDeform || (dataMask & ob->lastDataMask) != dataMask)
- mesh_build_data(scene, ob, dataMask);
+ mesh_build_data(scene, ob, dataMask, 0);
return ob->derivedDeform;
}
@@ -1569,7 +2046,7 @@ DerivedMesh *mesh_create_derived_render(Scene *scene, Object *ob, CustomDataMask
{
DerivedMesh *final;
- mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 1, 1, 0, dataMask, -1, 0);
+ mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 1, 1, 0, dataMask, -1, 0, 0);
return final;
}
@@ -1578,7 +2055,7 @@ DerivedMesh *mesh_create_derived_index_render(Scene *scene, Object *ob, CustomDa
{
DerivedMesh *final;
- mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 1, 1, 0, dataMask, index, 0);
+ mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 1, 1, 0, dataMask, index, 0, 0);
return final;
}
@@ -1587,7 +2064,7 @@ DerivedMesh *mesh_create_derived_view(Scene *scene, Object *ob, CustomDataMask d
{
DerivedMesh *final;
- mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 0, 1, 0, dataMask, -1, 0);
+ mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 0, 1, 0, dataMask, -1, 0, 0);
return final;
}
@@ -1597,7 +2074,7 @@ DerivedMesh *mesh_create_derived_no_deform(Scene *scene, Object *ob, float (*ver
{
DerivedMesh *final;
- mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 0, 0, 0, dataMask, -1, 0);
+ mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 0, 0, 0, dataMask, -1, 0, 0);
return final;
}
@@ -1607,7 +2084,7 @@ DerivedMesh *mesh_create_derived_no_virtual(Scene *scene, Object *ob, float (*ve
{
DerivedMesh *final;
- mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 0, -1, 0, dataMask, -1, 0);
+ mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 0, -1, 0, dataMask, -1, 0, 0);
return final;
}
@@ -1617,7 +2094,7 @@ DerivedMesh *mesh_create_derived_physics(Scene *scene, Object *ob, float (*vertC
{
DerivedMesh *final;
- mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 0, -1, 1, dataMask, -1, 0);
+ mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 0, -1, 1, dataMask, -1, 0, 0);
return final;
}
@@ -1628,14 +2105,14 @@ DerivedMesh *mesh_create_derived_no_deform_render(Scene *scene, Object *ob,
{
DerivedMesh *final;
- mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 1, 0, 0, dataMask, -1, 0);
+ mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 1, 0, 0, dataMask, -1, 0, 0);
return final;
}
/***/
-DerivedMesh *editmesh_get_derived_cage_and_final(Scene *scene, Object *obedit, EditMesh *em, DerivedMesh **final_r,
+DerivedMesh *editbmesh_get_derived_cage_and_final(Scene *scene, Object *obedit, BMEditMesh *em, DerivedMesh **final_r,
CustomDataMask dataMask)
{
/* if there's no derived mesh or the last data mask used doesn't include
@@ -1643,27 +2120,27 @@ DerivedMesh *editmesh_get_derived_cage_and_final(Scene *scene, Object *obedit, E
*/
if(!em->derivedCage ||
(em->lastDataMask & dataMask) != dataMask)
- editmesh_build_data(scene, obedit, em, dataMask);
+ editbmesh_build_data(scene, obedit, em, dataMask);
*final_r = em->derivedFinal;
return em->derivedCage;
}
-DerivedMesh *editmesh_get_derived_cage(Scene *scene, Object *obedit, EditMesh *em, CustomDataMask dataMask)
+DerivedMesh *editbmesh_get_derived_cage(Scene *scene, Object *obedit, BMEditMesh *em, CustomDataMask dataMask)
{
/* if there's no derived mesh or the last data mask used doesn't include
* the data we need, rebuild the derived mesh
*/
if(!em->derivedCage ||
(em->lastDataMask & dataMask) != dataMask)
- editmesh_build_data(scene, obedit, em, dataMask);
+ editbmesh_build_data(scene, obedit, em, dataMask);
return em->derivedCage;
}
-DerivedMesh *editmesh_get_derived_base(Object *UNUSED(obedit), EditMesh *em)
+DerivedMesh *editbmesh_get_derived_base(Object *obedit, BMEditMesh *em)
{
- return editmesh_get_derived(em, NULL);
+ return getEditDerivedBMesh(em, obedit, NULL);
}
@@ -1703,7 +2180,7 @@ float *mesh_get_mapped_verts_nors(Scene *scene, Object *ob)
if(ob->type!=OB_MESH || me->totvert==0)
return NULL;
- dm= mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
+ dm= mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH|CD_MASK_ORIGINDEX);
vertexcosnos= MEM_callocN(6*sizeof(float)*me->totvert, "vertexcosnos map");
if(dm->foreachMappedVert) {
@@ -1733,7 +2210,7 @@ typedef struct
MVert * mvert; // vertices & normals
float (*orco)[3];
float (*tangent)[4]; // destination
- int numFaces;
+ int numTessFaces;
} SGLSLMeshToTangent;
@@ -1743,7 +2220,7 @@ typedef struct
static int GetNumFaces(const SMikkTSpaceContext * pContext)
{
SGLSLMeshToTangent * pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData;
- return pMesh->numFaces;
+ return pMesh->numTessFaces;
}
static int GetNumVertsOfFace(const SMikkTSpaceContext * pContext, const int face_num)
@@ -1832,15 +2309,15 @@ void DM_add_tangent_layer(DerivedMesh *dm)
if(CustomData_get_layer_index(&dm->faceData, CD_TANGENT) != -1)
return;
- nors = dm->getFaceDataArray(dm, CD_NORMAL);
+ nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
/* check we have all the needed layers */
totvert= dm->getNumVerts(dm);
- totface= dm->getNumFaces(dm);
+ totface= dm->getNumTessFaces(dm);
mvert= dm->getVertArray(dm);
- mface= dm->getFaceArray(dm);
- mtface= dm->getFaceDataArray(dm, CD_MTFACE);
+ mface= dm->getTessFaceArray(dm);
+ mtface= dm->getTessFaceDataArray(dm, CD_MTFACE);
if(!mtface) {
orco= dm->getVertDataArray(dm, CD_ORCO);
@@ -1849,8 +2326,8 @@ void DM_add_tangent_layer(DerivedMesh *dm)
}
/* create tangent layer */
- DM_add_face_layer(dm, CD_TANGENT, CD_CALLOC, NULL);
- tangent= DM_get_face_data_layer(dm, CD_TANGENT);
+ DM_add_tessface_layer(dm, CD_TANGENT, CD_CALLOC, NULL);
+ tangent= DM_get_tessface_data_layer(dm, CD_TANGENT);
/* allocate some space */
arena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "tangent layer arena");
@@ -1870,7 +2347,7 @@ void DM_add_tangent_layer(DerivedMesh *dm)
mesh2tangent.mvert = mvert;
mesh2tangent.orco = orco;
mesh2tangent.tangent = tangent;
- mesh2tangent.numFaces = totface;
+ mesh2tangent.numTessFaces = totface;
sContext.m_pUserData = &mesh2tangent;
sContext.m_pInterface = &sInterface;
@@ -1963,11 +2440,11 @@ void DM_add_tangent_layer(DerivedMesh *dm)
void DM_calc_auto_bump_scale(DerivedMesh *dm)
{
/* int totvert= dm->getNumVerts(dm); */ /* UNUSED */
- int totface= dm->getNumFaces(dm);
+ int totface= dm->getNumTessFaces(dm);
MVert * mvert = dm->getVertArray(dm);
- MFace * mface = dm->getFaceArray(dm);
- MTFace * mtface = dm->getFaceDataArray(dm, CD_MTFACE);
+ MFace * mface = dm->getTessFaceArray(dm);
+ MTFace * mtface = dm->getTessFaceDataArray(dm, CD_MTFACE);
if(mtface)
{
@@ -2124,15 +2601,8 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
memset(attribs, 0, sizeof(DMVertexAttribs));
vdata = &dm->vertData;
- fdata = &dm->faceData;
-
- /* ugly hack, editmesh derivedmesh doesn't copy face data, this way we
- * can use offsets instead */
- if(dm->type == DM_TYPE_EDITMESH)
- tfdata = &((EditMeshDerivedMesh*)dm)->em->fdata;
- else
- tfdata = fdata;
-
+ fdata = tfdata = dm->getTessFaceDataLayout(dm);
+
/* calc auto bump scale if necessary */
if(dm->auto_bump_scale<=0.0f)
DM_calc_auto_bump_scale(dm);
@@ -2158,8 +2628,30 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
attribs->tface[a].array = tfdata->layers[layer].data;
attribs->tface[a].emOffset = tfdata->layers[layer].offset;
attribs->tface[a].glIndex = gattribs->layer[b].glindex;
- attribs->tface[a].glTexco = gattribs->layer[b].gltexco;
+ /* attribs->tface[a].glTexco = gattribs->layer[b].gltexco; */ /* BMESH_TODO, trunk has this but not bmesh, need to investigate whats going on here - campbell */
+ }
+ /* BMESH ONLY, may need to get this working?, otherwise remove */
+ /* else {
+ int player;
+ CustomData *pdata = dm->getPolyDataLayout(dm);
+
+ if(gattribs->layer[b].name[0])
+ player = CustomData_get_named_layer_index(pdata, CD_MTEXPOLY,
+ gattribs->layer[b].name);
+ else
+ player = CustomData_get_active_layer_index(pdata, CD_MTEXPOLY);
+
+ if (player != -1) {
+ a = attribs->tottface++;
+
+ attribs->tface[a].array = NULL;
+ attribs->tface[a].emOffset = pdata->layers[layer].offset;
+ attribs->tface[a].glIndex = gattribs->layer[b].glindex;
+ attribs->tface[a].glTexco = gattribs->layer[b].gltexco;
+
+ }
}
+ */
}
else if(gattribs->layer[b].type == CD_MCOL) {
/* vertex colors */
@@ -2223,6 +2715,15 @@ void DM_set_object_boundbox(Object *ob, DerivedMesh *dm)
/* --- NAVMESH (begin) --- */
#ifdef WITH_GAMEENGINE
+/* BMESH_TODO, navmesh is not working right currently
+ * All tools set this as MPoly data, but derived mesh currently draws from MFace (tessface)
+ *
+ * Proposed solution, rather then copy CD_RECAST into the MFace array,
+ * use ORIGINDEX to get the original poly index and then get the CD_RECAST
+ * data from the original me->mpoly layer. - campbell
+ */
+
+
BM_INLINE int navmesh_bit(int a, int b)
{
return (a & (1 << b)) >> b;
@@ -2262,7 +2763,7 @@ static void navmesh_drawColored(DerivedMesh *dm)
DEBUG_VBO( "Using legacy code. drawNavMeshColored\n" );
//glShadeModel(GL_SMOOTH);
glBegin(glmode = GL_QUADS);
- for(a = 0; a < dm->numFaceData; a++, mface++) {
+ for(a = 0; a < dm->numTessFaceData; a++, mface++) {
int new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES;
int pi = polygonIdx[a];
if (pi <= 0) {
@@ -2315,7 +2816,7 @@ static void navmesh_DM_drawFacesSolid(DerivedMesh *dm,
static DerivedMesh *navmesh_dm_createNavMeshForVisualization(DerivedMesh *dm)
{
DerivedMesh *result;
- int maxFaces = dm->getNumFaces(dm);
+ int maxFaces = dm->getNumPolys(dm);
int *recastData;
int vertsPerPoly=0, nverts=0, ndtris=0, npolys=0;
float* verts=NULL;
@@ -2393,6 +2894,30 @@ static DerivedMesh *navmesh_dm_createNavMeshForVisualization(DerivedMesh *dm)
/* --- NAVMESH (end) --- */
+void DM_init_origspace(DerivedMesh *dm)
+{
+ static float default_osf[4][2] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
+
+ OrigSpaceLoop *lof_array = CustomData_get_layer(&dm->loopData, CD_ORIGSPACE_MLOOP);
+ OrigSpaceLoop *lof;
+ const int numpoly = dm->getNumPolys(dm);
+ // const int numloop = dm->getNumLoops(dm);
+ MPoly *mp = dm->getPolyArray(dm);
+ int i, j;
+
+ for (i = 0; i < numpoly; i++, mp++) {
+ /* only quads/tri's for now */
+ if (mp->totloop == 3 || mp->totloop == 4) {
+ lof = lof_array + mp->loopstart;
+ for (j = 0; j < mp->totloop; j++, lof++) {
+ copy_v2_v2(lof->uv, default_osf[j]);
+ }
+ }
+ }
+}
+
+
+
/* derivedmesh info printing function,
* to help track down differences DM output */
@@ -2429,26 +2954,35 @@ char *DM_debug_info(DerivedMesh *dm)
BLI_dynstr_appendf(dynstr, " 'ptr': '%p',\n", (void *)dm);
switch (dm->type) {
case DM_TYPE_CDDM: tstr = "DM_TYPE_CDDM"; break;
- case DM_TYPE_EDITMESH: tstr = "DM_TYPE_EDITMESH"; break;
+ case DM_TYPE_EDITBMESH: tstr = "DM_TYPE_EDITMESH"; break;
case DM_TYPE_CCGDM: tstr = "DM_TYPE_CCGDM"; break;
default: tstr = "UNKNOWN"; break;
}
BLI_dynstr_appendf(dynstr, " 'type': '%s',\n", tstr);
BLI_dynstr_appendf(dynstr, " 'numVertData': %d,\n", dm->numVertData);
BLI_dynstr_appendf(dynstr, " 'numEdgeData': %d,\n", dm->numEdgeData);
- BLI_dynstr_appendf(dynstr, " 'numFaceData': %d,\n", dm->numFaceData);
+ BLI_dynstr_appendf(dynstr, " 'numTessFaceData': %d,\n", dm->numTessFaceData);
+ BLI_dynstr_appendf(dynstr, " 'numPolyData': %d,\n", dm->numPolyData);
BLI_dynstr_appendf(dynstr, " 'deformedOnly': %d,\n", dm->deformedOnly);
BLI_dynstr_appendf(dynstr, " 'vertexLayers': (\n");
dm_debug_info_layers(dynstr, dm, dm->getVertDataArray);
BLI_dynstr_appendf(dynstr, " ),\n");
+ BLI_dynstr_appendf(dynstr, " 'loopLayers': (\n");
+ dm_debug_info_layers(dynstr, dm, DM_get_loop_data_layer);
+ BLI_dynstr_appendf(dynstr, " ),\n");
+
BLI_dynstr_appendf(dynstr, " 'edgeLayers': (\n");
dm_debug_info_layers(dynstr, dm, dm->getEdgeDataArray);
BLI_dynstr_appendf(dynstr, " ),\n");
- BLI_dynstr_appendf(dynstr, " 'faceLayers': (\n");
- dm_debug_info_layers(dynstr, dm, dm->getFaceDataArray);
+ BLI_dynstr_appendf(dynstr, " 'tessFaceLayers': (\n");
+ dm_debug_info_layers(dynstr, dm, dm->getTessFaceDataArray);
+ BLI_dynstr_appendf(dynstr, " ),\n");
+
+ BLI_dynstr_appendf(dynstr, " 'polyLayers': (\n");
+ dm_debug_info_layers(dynstr, dm, DM_get_poly_data_layer);
BLI_dynstr_appendf(dynstr, " ),\n");
BLI_dynstr_appendf(dynstr, "}\n");