Add CD_POLYINDEX layer to reduce need for retesselations

This commit is contained in:
2011-11-13 15:13:59 +00:00
parent c0934795cb
commit 2266c7fc1c
21 changed files with 176 additions and 154 deletions

View File

@@ -129,11 +129,14 @@ struct DerivedMesh {
struct GPUDrawObject *drawObject;
DerivedMeshType type;
/* Misc. Queries */
/*recalculates mesh tesselation*/
/* calculate vert and face normals */
void (*calcNormals)(DerivedMesh *dm);
/* recalculates mesh tesselation */
void (*recalcTesselation)(DerivedMesh *dm);
/* Misc. Queries */
/* Also called in Editmode */
int (*getNumVerts)(DerivedMesh *dm);
int (*getNumEdges)(DerivedMesh *dm);
@@ -166,8 +169,8 @@ struct DerivedMesh {
void (*copyVertArray)(DerivedMesh *dm, struct MVert *vert_r);
void (*copyEdgeArray)(DerivedMesh *dm, struct MEdge *edge_r);
void (*copyTessFaceArray)(DerivedMesh *dm, struct MFace *face_r);
void (*copyLoopArray)(DerivedMesh *dm, struct MLoop *loop_r);
void (*copyPolyArray)(DerivedMesh *dm, struct MPoly *poly_r);
void (*copyLoopArray)(DerivedMesh *dm, struct MLoop *loop_r);
void (*copyPolyArray)(DerivedMesh *dm, struct MPoly *poly_r);
/* return a copy of all verts/edges/faces from the derived mesh
* it is the caller's responsibility to free the returned pointer
@@ -175,8 +178,8 @@ struct DerivedMesh {
struct MVert *(*dupVertArray)(DerivedMesh *dm);
struct MEdge *(*dupEdgeArray)(DerivedMesh *dm);
struct MFace *(*dupTessFaceArray)(DerivedMesh *dm);
struct MLoop *(*dupLoopArray)(DerivedMesh *dm);
struct MPoly *(*dupPolyArray)(DerivedMesh *dm);
struct MLoop *(*dupLoopArray)(DerivedMesh *dm);
struct MPoly *(*dupPolyArray)(DerivedMesh *dm);
/* return a pointer to a single element of vert/edge/face custom data
* from the derived mesh (this gives a pointer to the actual data, not

View File

@@ -111,11 +111,8 @@ void CDDM_calc_edges(struct DerivedMesh *dm);
faces*/
void CDDM_calc_edges_poly(struct DerivedMesh *dm);
/*reconstitute face triangulation. if orig_use_polyorig is nonzero, sets
the mface origindex layer to copy to the origindex values of the
parent mpolys; otherwise the mface origindex will point to the index of
the parent mpoly*/
void CDDM_recalc_tesselation(struct DerivedMesh *dm, int orig_use_polyorig);
/* reconstitute face triangulation */
void CDDM_recalc_tesselation(struct DerivedMesh *dm);
/* lowers the number of vertices/edges/faces in a CDDerivedMesh
* the layer data stays the same size

View File

@@ -75,7 +75,7 @@ struct BMesh *BKE_mesh_to_bmesh(struct Mesh *me, struct Object *ob);
*/
int mesh_recalcTesselation(struct CustomData *fdata, struct CustomData *ldata,
struct CustomData *pdata, struct MVert *mvert, int totface,
int totloop, int totpoly, int use_poly_origindex, int use_face_origindex);
int totloop, int totpoly);
/*calculates a face normal.*/
void mesh_calc_poly_normal(struct MPoly *mpoly, struct MLoop *loopstart,

View File

@@ -365,13 +365,11 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob)
totvert = tmp.totvert = dm->getNumVerts(dm);
totedge = tmp.totedge = dm->getNumEdges(dm);
totface = tmp.totface = dm->getNumTessFaces(dm);
totpoly = tmp.totpoly = dm->getNumFaces(dm);
totloop = tmp.totloop = dm->numLoopData;
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);
@@ -406,8 +404,6 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob)
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->dupTessFaceArray(dm), totface);
if(!CustomData_has_layer(&tmp.pdata, CD_MPOLY)) {
tmp.mloop = dm->dupLoopArray(dm);
tmp.mpoly = dm->dupPolyArray(dm);
@@ -425,6 +421,7 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob)
}
}
tmp.totface = mesh_recalcTesselation(&tmp.fdata, &tmp.ldata, &tmp.pdata, tmp.mvert, tmp.totface, tmp.totloop, tmp.totpoly);
mesh_update_customdata_pointers(&tmp);
CustomData_free(&me->vdata, me->totvert);
@@ -530,7 +527,7 @@ void *DM_get_edge_data_layer(DerivedMesh *dm, int type)
void *DM_get_tessface_data_layer(DerivedMesh *dm, int type)
{
if(type == CD_MFACE)
if (type == CD_MFACE)
return dm->getTessFaceArray(dm);
return CustomData_get_layer(&dm->faceData, type);
@@ -1457,6 +1454,8 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
}
#endif /* WITH_GAMEENGINE */
finaldm->calcNormals(finaldm);
*final_r = finaldm;
if(orcodm)
@@ -1508,7 +1507,7 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
ModifierData *md;
float (*deformedVerts)[3] = NULL;
CustomDataMask mask;
DerivedMesh *dm = NULL, *orcodm = NULL;
DerivedMesh *dm = NULL, *orcodm = NULL, *finaldm = NULL;
int i, numVerts = 0, cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1);
LinkNode *datamasks, *curr;
int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
@@ -1660,21 +1659,24 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
* then we need to build one.
*/
if(dm && deformedVerts) {
*final_r = CDDM_copy(dm, 0);
finaldm = CDDM_copy(dm, 0);
if(!(cage_r && dm == *cage_r)) dm->release(dm);
CDDM_apply_vert_coords(*final_r, deformedVerts);
CDDM_calc_normals(*final_r);
} else if (dm) {
*final_r = dm;
finaldm = dm;
} else if (!deformedVerts && cage_r && *cage_r) {
*final_r = *cage_r;
finaldm = *cage_r;
} else {
*final_r = getEditDerivedBMesh(em, ob, deformedVerts);
finaldm = getEditDerivedBMesh(em, ob, deformedVerts);
deformedVerts = NULL;
}
finaldm->calcNormals(finaldm);
*final_r = finaldm;
/* add an orco layer if needed */
if(dataMask & CD_MASK_ORCO)
add_orco_dm(ob, em, *final_r, orcodm, CD_ORCO);

View File

@@ -1580,37 +1580,17 @@ static void cdDM_foreachMappedFaceCenter(
}
static void cdDM_recalcTesselation(DerivedMesh *dm)
void CDDM_recalc_tesselation(DerivedMesh *dm)
{
CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
dm->numFaceData = mesh_recalcTesselation(&dm->faceData, &dm->loopData,
&dm->polyData, cddm->mvert, dm->numFaceData, dm->numLoopData,
dm->numPolyData, 1, 0);
dm->numPolyData);
cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
}
/*ignores original poly origindex layer*/
static void cdDM_recalcTesselation2(DerivedMesh *dm)
{
CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
dm->numFaceData = mesh_recalcTesselation(&dm->faceData, &dm->loopData,
&dm->polyData, cddm->mvert, dm->numFaceData, dm->numLoopData,
dm->numPolyData, 0, 0);
cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
}
void CDDM_recalc_tesselation(DerivedMesh *dm, int orig_use_polyorig)
{
if (orig_use_polyorig)
cdDM_recalcTesselation(dm);
else
cdDM_recalcTesselation2(dm);
}
static void cdDM_free_internal(CDDerivedMesh *cddm)
{
if(cddm->fmap) MEM_freeN(cddm->fmap);
@@ -1662,9 +1642,10 @@ static CDDerivedMesh *cdDM_create(const char *desc)
dm->getVertDataArray = DM_get_vert_data_layer;
dm->getEdgeDataArray = DM_get_edge_data_layer;
dm->getTessFaceDataArray = DM_get_tessface_data_layer;
dm->calcNormals = CDDM_calc_normals;
//doesn't work yet for all cases
//dm->recalcTesselation = cdDM_recalcTesselation;
//dm->recalcTesselation = CDDM_recalc_tesselation;
dm->getVertCos = cdDM_getVertCos;
dm->getVertCo = cdDM_getVertCo;
@@ -1708,6 +1689,7 @@ DerivedMesh *CDDM_new(int numVerts, int numEdges, int numFaces, int numLoops, in
CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFaces);
CustomData_add_layer(&dm->faceData, CD_POLYINDEX, CD_CALLOC, NULL, numFaces);
CustomData_add_layer(&dm->polyData, CD_ORIGINDEX, CD_CALLOC, NULL, numPolys);
CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
@@ -1731,6 +1713,7 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob))
DerivedMesh *dm = &cddm->dm;
CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS);
int alloctype;
int *polyindex = NULL;
/* this does a referenced copy, with an exception for fluidsim */
@@ -1745,7 +1728,7 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob))
mesh->totvert);
CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype,
mesh->totedge);
CustomData_merge(&mesh->fdata, &dm->faceData, mask|CD_MASK_ORIGINDEX, alloctype,
CustomData_merge(&mesh->fdata, &dm->faceData, mask|CD_MASK_POLYINDEX, alloctype,
mesh->totface);
CustomData_merge(&mesh->ldata, &dm->loopData, mask, alloctype,
mesh->totloop);
@@ -1758,8 +1741,12 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob))
cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
if (!CustomData_has_layer(&cddm->dm.faceData, CD_ORIGINDEX))
CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totface);
BLI_assert(CustomData_has_layer(&cddm->dm.faceData, CD_POLYINDEX));
polyindex = CustomData_get_layer(&dm->faceData, CD_POLYINDEX);
if (!CustomData_has_layer(&cddm->dm.faceData, CD_ORIGINDEX)) {
CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_REFERENCE, polyindex, mesh->totface);
}
return dm;
}
@@ -1841,7 +1828,7 @@ static DerivedMesh *disabled__CDDM_from_editmesh(EditMesh *em, Mesh *UNUSED(me))
/* CustomData_from_em_block(&em->edata, &dm->edgeData, eed->data, i); */
}
index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
index = dm->getTessFaceDataArray(dm, CD_POLYINDEX);
for(i = 0, efa = em->faces.first; i < dm->numFaceData;
i++, efa = efa->next, index++) {
MFace *mf = &mface[i];
@@ -1980,7 +1967,7 @@ DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *UNUSED(me), int use_mdis
MPoly *mpoly = cddm->mpoly;
int numCol = CustomData_number_of_layers(&em->bm->ldata, CD_MLOOPCOL);
int numTex = CustomData_number_of_layers(&em->bm->pdata, CD_MTEXPOLY);
int i, j, *index, add_orig;
int i, j, *index, *polyindex, add_orig;
int has_crease, has_edge_bweight, has_vert_bweight;
int flag;
@@ -2063,6 +2050,7 @@ DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *UNUSED(me), int use_mdis
BM_SetIndex(efa, i);
}
polyindex = dm->getTessFaceDataArray(dm, CD_POLYINDEX);
index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
for(i = 0; i < dm->numFaceData; i++, index++) {
MFace *mf = &mface[i];
@@ -2077,6 +2065,7 @@ DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *UNUSED(me), int use_mdis
mf->flag = BMFlags_To_MEFlags(efa);
*index = add_orig ? BM_GetIndex(efa) : *(int*)CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_ORIGINDEX);
*polyindex = BM_GetIndex(efa);
loops_to_customdata_corners(bm, &dm->faceData, i, l, numCol, numTex);
test_index_face(mf, &dm->faceData, i, 3);
@@ -2151,8 +2140,10 @@ DerivedMesh *CDDM_copy(DerivedMesh *source, int faces_from_tessfaces)
cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
cdDM_recalcTesselation((DerivedMesh *)cddm);
/* BMESH_TODO: Find out why this is necessary (or else find a way to remove
it). If it is necessary, add a comment explaining why. */
CDDM_recalc_tesselation((DerivedMesh *)cddm);
return dm;
}
@@ -2187,6 +2178,8 @@ DerivedMesh *CDDM_from_template(DerivedMesh *source,
CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
if(!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX))
CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFaces);
if(!CustomData_get_layer(&dm->faceData, CD_POLYINDEX))
CustomData_add_layer(&dm->faceData, CD_POLYINDEX, CD_CALLOC, NULL, numFaces);
cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
@@ -2234,21 +2227,23 @@ void CDDM_calc_normals(DerivedMesh *dm)
/* we don't want to overwrite any referenced layers */
cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
/*set tesselation origindex values to map to poly indices, rather then poly
poly origindex values*/
cdDM_recalcTesselation2(dm);
if (dm->numFaceData == 0) {
/* No tesselation on this mesh yet, need to calculate one */
CDDM_recalc_tesselation(dm);
}
else {
/* A tesselation already exists, it should always have a CD_POLYINDEX */
BLI_assert(CustomData_has_layer(&dm->faceData, CD_POLYINDEX));
}
face_nors = MEM_mallocN(sizeof(float)*3*dm->numFaceData, "face_nors");
/* calculate face normals */
mesh_calc_normals(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
dm->numLoopData, dm->numPolyData, NULL, cddm->mface, dm->numFaceData,
CustomData_get_layer(&dm->faceData, CD_ORIGINDEX), face_nors);
CustomData_get_layer(&dm->faceData, CD_POLYINDEX), face_nors);
/*restore tesselation origindex indices to poly origindex indices*/
cdDM_recalcTesselation(dm);
CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_ASSIGN,
face_nors, dm->numFaceData);
}
@@ -2424,7 +2419,7 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, int *vtargetmap)
memcpy(cddm2->mpoly, mpoly, sizeof(MPoly)*BLI_array_count(mpoly));
BLI_array_free(mvert); BLI_array_free(medge); BLI_array_free(mloop); BLI_array_free(mpoly);
CDDM_recalc_tesselation((DerivedMesh*)cddm2, 1);
CDDM_recalc_tesselation((DerivedMesh*)cddm2);
if (newv)
MEM_freeN(newv);
@@ -2657,7 +2652,7 @@ void CDDM_tessfaces_to_faces(DerivedMesh *dm)
MLoop *ml;
MPoly *mp;
EdgeHash *eh = BLI_edgehash_new();
int i, l, totloop, *index1, *index2;
int i, l, totloop, *polyindex;
/*ensure we have all the edges we need*/
CDDM_calc_edges(dm);
@@ -2690,8 +2685,7 @@ void CDDM_tessfaces_to_faces(DerivedMesh *dm)
CustomData_merge(&cddm->dm.faceData, &cddm->dm.polyData,
CD_MASK_ORIGINDEX, CD_DUPLICATE, cddm->dm.numFaceData);
index1 = CustomData_get_layer(&cddm->dm.faceData, CD_ORIGINDEX);
index2 = CustomData_get_layer(&cddm->dm.polyData, CD_ORIGINDEX);
polyindex = CustomData_get_layer(&cddm->dm.faceData, CD_POLYINDEX);
mf = cddm->mface;
mp = cddm->mpoly;
@@ -2721,7 +2715,7 @@ void CDDM_tessfaces_to_faces(DerivedMesh *dm)
ml++, l++;
}
*index2 = *index1;
*polyindex = i;
}
BLI_edgehash_free(eh, NULL);

View File

@@ -1048,8 +1048,8 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
/* 8: CD_NORMAL */
/* 3 floats per normal vector */
{sizeof(float)*3, "vec3f", 1, NULL, NULL, NULL, NULL, NULL, NULL},
/* 9: CD_FLAGS */
{sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
/* 9: CD_POLYINDEX */
{sizeof(int), "MIntProperty", 1, NULL, NULL, NULL, NULL, NULL, NULL},
/* 10: CD_PROP_FLT */
{sizeof(MFloatProperty), "MFloatProperty",1,"Float", layerCopy_propFloat,NULL,NULL,NULL},
/* 11: CD_PROP_INT */
@@ -1103,7 +1103,7 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
/* 0-4 */ "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace",
/* 5-9 */ "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty",
/* 5-9 */ "CDMCol", "CDOrigIndex", "CDNormal", "CDPolyIndex","CDMFloatProperty",
/* 10-14 */ "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV",
/* 15-19 */ "CDMloopCol", "CDTangent", "CDMDisps", "CDWeightMCol", "CDMPoly",
/* 20-24 */ "CDMLoop", "CDMClothOrco", "CDMLoopCol", "CDIDCol", "CDTextureCol",
@@ -1126,10 +1126,11 @@ const CustomDataMask CD_MASK_EDITMESH =
CD_MASK_MDISPS | CD_MASK_SHAPEKEY | CD_MASK_RECAST;
const CustomDataMask CD_MASK_DERIVEDMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_CLOTH_ORCO |
CD_MASK_MCOL | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_CLOTH_ORCO |
CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_WEIGHT_MLOOPCOL |
CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT |
CD_MASK_WEIGHT_MCOL | CD_MASK_NORMAL | CD_MASK_SHAPEKEY | CD_MASK_RECAST;
CD_MASK_WEIGHT_MCOL | CD_MASK_NORMAL | CD_MASK_SHAPEKEY | CD_MASK_RECAST |
CD_MASK_ORIGINDEX | CD_MASK_POLYINDEX;
const CustomDataMask CD_MASK_BMESH = CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY |
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT |
CD_MASK_PROP_STR | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_MDISPS;

View File

@@ -362,6 +362,12 @@ static void bmdm_recalc_lookups(EditDerivedBMesh *bmdm)
}
}
static void bmDM_calcNormals(DerivedMesh *UNUSED(dm))
{
/* Nothing to do: normals are already calculated and stored on the
BMVerts and BMFaces */
}
static void bmDM_recalcTesselation(DerivedMesh *UNUSED(dm))
{
//EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
@@ -1668,6 +1674,7 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em, Object *UNUSED(ob),
bmdm->dm.getTessFaceDataArray = bmDM_getFaceDataArray;
bmdm->dm.calcNormals = bmDM_calcNormals;
bmdm->dm.recalcTesselation = bmDM_recalcTesselation;
bmdm->dm.foreachMappedVert = bmDM_foreachMappedVert;

View File

@@ -1142,6 +1142,12 @@ void mball_to_mesh(ListBase *lb, Mesh *me)
make_edges(me, 0); // all edges
convert_mfaces_to_mpolys(me);
me->totface = mesh_recalcTesselation(
&me->fdata, &me->ldata, &me->pdata,
me->mvert, me->totface, me->totloop, me->totpoly);
mesh_update_customdata_pointers(me);
}
}
@@ -1968,6 +1974,8 @@ void convert_mfaces_to_mpolys(Mesh *mesh)
/* note, we dont convert FGons at all, these are not even real ngons,
* they have their own UV's, colors etc - its more an editing feature. */
mesh_update_customdata_pointers(mesh);
BLI_edgehash_free(eh, NULL);
}
@@ -1978,7 +1986,7 @@ float (*mesh_getVertexCos(Mesh *me, int *numVerts_r))[3]
if (numVerts_r) *numVerts_r = numVerts;
for (i=0; i<numVerts; i++)
VECCOPY(cos[i], me->mvert[i].co);
copy_v3_v3(cos[i], me->mvert[i].co);
return cos;
}
@@ -2260,21 +2268,11 @@ void mesh_loops_to_tri_corners(CustomData *fdata, CustomData *ldata,
/*
this function recreates a tesselation.
returns number of tesselation faces.
use_poly_origindex sets whether or not the tesselation faces' origindex
layer should point to original poly indices or real poly indices.
use_face_origindex sets the tesselation faces' origindex layer
to point to the tesselation faces themselves, not the polys.
if both of the above are 0, it'll use the indices of the mpolys of the MPoly
data in pdata, and ignore the origindex layer altogether.
*/
int mesh_recalcTesselation(CustomData *fdata,
CustomData *ldata, CustomData *pdata,
MVert *mvert, int totface, int UNUSED(totloop),
int totpoly, int use_poly_origindex,
int use_face_origindex)
int totpoly)
{
MPoly *mp, *mpoly;
MLoop *ml, *mloop;
@@ -2282,8 +2280,11 @@ int mesh_recalcTesselation(CustomData *fdata,
BLI_array_declare(mf);
EditVert *v, *lastv, *firstv;
EditFace *f;
int *origIndex = NULL;
BLI_array_declare(origIndex);
int i, j, k, lindex[4], *origIndex = NULL, *polyorigIndex;
int *polyIndex = NULL;
BLI_array_declare(polyIndex);
int i, j, k, lindex[4], *polyorigIndex;
int numTex, numCol;
mpoly = CustomData_get_layer(pdata, CD_MPOLY);
@@ -2294,7 +2295,7 @@ int mesh_recalcTesselation(CustomData *fdata,
k = 0;
mp = mpoly;
polyorigIndex = use_poly_origindex? CustomData_get_layer(pdata, CD_ORIGINDEX) : NULL;
polyorigIndex = CustomData_get_layer(pdata, CD_ORIGINDEX);
for (i=0; i<totpoly; i++, mp++) {
if (mp->totloop > 2) {
ml = mloop + mp->loopstart;
@@ -2304,10 +2305,6 @@ int mesh_recalcTesselation(CustomData *fdata,
lastv = NULL;
for (j=0; j<mp->totloop; j++, ml++) {
v = BLI_addfillvert(mvert[ml->v].co);
if (polyorigIndex && use_poly_origindex)
v->hash = polyorigIndex[i];
else
v->hash = i;
v->keyindex = mp->loopstart + j;
@@ -2323,20 +2320,21 @@ int mesh_recalcTesselation(CustomData *fdata,
BLI_edgefill(2);
for (f=fillfacebase.first; f; f=f->next) {
BLI_array_growone(mf);
BLI_array_growone(origIndex);
BLI_array_append(polyIndex, i);
/*these are loop indices, they'll be transformed
into vert indices later.*/
mf[k].v1 = f->v1->keyindex;
mf[k].v2 = f->v2->keyindex;
mf[k].v3 = f->v3->keyindex;
/*put poly index in mf->v4*/
mf[k].v4 = f->v1->hash;
mf[k].v4 = 0;
mf[k].mat_nr = mp->mat_nr;
mf[k].flag = mp->flag;
origIndex[k] = use_face_origindex ? k : f->v1->hash;
if (polyorigIndex) {
BLI_array_append(origIndex, polyorigIndex[polyIndex[k]]);
}
k++;
}
@@ -2350,9 +2348,23 @@ int mesh_recalcTesselation(CustomData *fdata,
totface = k;
CustomData_add_layer(fdata, CD_MFACE, CD_ASSIGN, mf, totface);
CustomData_add_layer(fdata, CD_ORIGINDEX, CD_ASSIGN, origIndex, totface);
CustomData_add_layer(fdata, CD_POLYINDEX, CD_ASSIGN, polyIndex, totface);
if (origIndex) {
CustomData_add_layer(fdata, CD_ORIGINDEX, CD_ASSIGN, origIndex, totface);
}
CustomData_from_bmeshpoly(fdata, pdata, ldata, totface);
/* If polys have a normals layer, copying that to faces can help
avoid the need to recalculate normals later */
if (CustomData_has_layer(pdata, CD_NORMAL)) {
float *pnors = CustomData_get_layer(pdata, CD_NORMAL);
float *fnors = CustomData_add_layer(fdata, CD_NORMAL, CD_CALLOC, NULL, totface);
for (i=0; i<totface; i++, fnors++) {
copy_v3_v3(fnors, &pnors[polyIndex[i]]);
}
}
mface = mf;
for (i=0; i<totface; i++, mf++) {
/*sort loop indices to ensure winding is correct*/
@@ -2374,9 +2386,7 @@ int mesh_recalcTesselation(CustomData *fdata,
mf->v3 = mloop[mf->v3].v;
mesh_loops_to_tri_corners(fdata, ldata, pdata,
lindex, i, mf->v4);
mf->v4 = 0;
lindex, i, polyIndex[i]);
}
return totface;
@@ -2450,7 +2460,6 @@ static void mesh_calc_ngon_normal(MPoly *mpoly, MLoop *loopstart,
normal[0] = (float) n[0];
normal[1] = (float) n[1];
normal[2] = (float) n[2];
}
void mesh_calc_poly_normal(MPoly *mpoly, MLoop *loopstart,

View File

@@ -2758,6 +2758,11 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
return ccgdm->pbvh;
}
static void ccgDM_calcNormals(DerivedMesh *UNUSED(dm))
{
/* Nothing to do: CCG calculates normals during drawing */
}
static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
int drawInteriorEdges,
int useSubsurfUv,
@@ -2847,6 +2852,8 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
ccgdm->dm.getEdgeData = DM_get_edge_data;
ccgdm->dm.getTessFaceData = DM_get_face_data;
ccgdm->dm.calcNormals = ccgDM_calcNormals;
ccgdm->dm.getVertCos = cgdm_getVertCos;
ccgdm->dm.foreachMappedVert = cgdm_foreachMappedVert;
ccgdm->dm.foreachMappedEdge = cgdm_foreachMappedEdge;
@@ -2867,7 +2874,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
ccgdm->dm.drawMappedEdgesInterp = cgdm_drawMappedEdgesInterp;
ccgdm->dm.drawMappedEdges = cgdm_drawMappedEdges;
ccgdm->dm.release = cgdm_release;
ccgdm->ss = ss;

View File

@@ -3657,6 +3657,22 @@ static void lib_link_mesh(FileData *fd, Main *main)
convert_mfaces_to_mpolys(me);
}
/*
* Re-tesselate, even if the polys were just created from tessfaces, this
* is important because it:
* - fill the CD_POLYINDEX layer
* - gives consistency of tessface between loading from a file and
* converting an edited BMesh back into a mesh (i.e. it replaces
* quad tessfaces in a loaded mesh immediately, instead of lazily
* waiting until edit mode has been entered/exited, making it easier
* to recognize problems that would otherwise only show up after edits).
*/
me->totface = mesh_recalcTesselation(
&me->fdata, &me->ldata, &me->pdata,
me->mvert, me->totface, me->totloop, me->totpoly);
mesh_update_customdata_pointers(me);
me->id.flag -= LIB_NEEDLINK;
}
me= me->id.next;

View File

@@ -428,7 +428,7 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op)
BMLoop *l;
BMFace *f;
BMIter iter, liter; float *facenors = NULL;
int i, j, *keyi, ototvert, totloop, totface, numTex, numCol;
int i, j, *keyi, ototvert, totloop, totface, numTex, numCol, *polyindex = NULL;
int dotess = !BMO_Get_Int(op, "notesselation");
numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
@@ -574,16 +574,18 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op)
else {
mface= MEM_callocN(totface*sizeof(MFace), "loadeditbMesh face");
facenors = MEM_callocN(totface*sizeof(float)*3, "facenors");
polyindex = MEM_callocN(totface*sizeof(int), "polyindex");
}
CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, mface, me->totface);
CustomData_add_layer(&me->fdata, CD_POLYINDEX, CD_ASSIGN, polyindex, me->totface);
CustomData_add_layer(&me->fdata, CD_NORMAL, CD_ASSIGN, facenors, me->totface);
CustomData_from_bmeshpoly(&me->fdata, &bm->pdata, &bm->ldata, totface);
mesh_update_customdata_pointers(me);
i = 0;
BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
BM_ITER_INDEX(f, &iter, bm, BM_FACES_OF_MESH, NULL, j) {
EditVert *eve, *lasteve = NULL, *firsteve = NULL;
EditFace *efa;
BMLoop *ls[3];
@@ -633,8 +635,11 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op)
loops_to_corners(bm, me, i, f, ls, numTex, numCol);
copy_v3_v3(facenors, ls[0]->f->no);
*polyindex = j;
mface++;
facenors += 3;
polyindex++;
i++;
}
BLI_end_edgefill();

View File

@@ -83,18 +83,19 @@ void paintface_flush_flags(Object *ob)
}
/*
* Try to push updated mesh poly flags to two other data sets:
* Try to push updated mesh poly flags to three other data sets:
* - Mesh polys => Mesh tess faces
* - Mesh polys => Final derived mesh polys
* - Mesh polys => Final derived polys
* - Final derived polys => Final derived tessfaces
*/
if ((index_array = CustomData_get_layer(&me->fdata, CD_ORIGINDEX))) {
if ((index_array = CustomData_get_layer(&me->fdata, CD_POLYINDEX))) {
faces = me->mface;
totface = me->totface;
/* loop over tessfaces */
for (i= 0; i<totface; i++) {
/* Copy flags onto the tessface from its poly */
/* Copy flags onto the original tessface from its original poly */
mp_orig = me->mpoly + index_array[i];
faces[i].flag = mp_orig->flag;
}
@@ -106,11 +107,24 @@ void paintface_flush_flags(Object *ob)
/* loop over final derived polys */
for (i= 0; i<totpoly; i++) {
/* Copy flags onto the mesh poly from its final derived poly */
/* Copy flags onto the final derived poly from the original mesh poly */
mp_orig = me->mpoly + index_array[i];
polys[i].flag = mp_orig->flag;
}
}
if ((index_array = CustomData_get_layer(&dm->faceData, CD_POLYINDEX))) {
polys = dm->getPolyArray(dm);
faces = dm->getTessFaceArray(dm);;
totface = dm->getNumTessFaces(dm);
/* loop over tessfaces */
for (i= 0; i<totface; i++) {
/* Copy flags onto the final tessface from its final poly */
mp_orig = polys + index_array[i];
faces[i].flag = mp_orig->flag;
}
}
}
/* returns 0 if not found, otherwise 1 */
@@ -123,14 +137,6 @@ static int facesel_face_pick(struct bContext *C, Mesh *me, Object *ob, const int
if (!me || me->totpoly==0)
return 0;
/*we can't assume mfaces have a correct origindex layer that indices to mpolys.
so instead we have to regenerate the tesselation faces altogether.
the final 0, 0 paramters causes it to use the index of each mpoly, instead
of reading from the origindex layer.*/
me->totface = mesh_recalcTesselation(&me->fdata, &me->ldata, &me->pdata,
me->mvert, me->totface, me->totloop, me->totpoly, 0, 0);
mesh_update_customdata_pointers(me);
makeDerivedMesh(scene, ob, NULL, CD_MASK_BAREMESH, 0);
// XXX if (v3d->flag & V3D_INVALID_BACKBUF) {

View File

@@ -664,15 +664,11 @@ void ED_mesh_update(Mesh *mesh, bContext *C, int calc_edges)
mesh->mvert,
mesh->totface,
mesh->totloop,
mesh->totpoly,
0,
0);
mesh->totpoly);
mesh_update_customdata_pointers(mesh);
/* origindex for tesselated faces currently holds indices of the poly
the face was tesselated from */
polyindex = CustomData_get_layer(&mesh->fdata, CD_ORIGINDEX);
polyindex = CustomData_get_layer(&mesh->fdata, CD_POLYINDEX);
/* add a normals layer for tesselated faces, a tessface normal will
contain the normal of the poly the face was tesselated from. */
face_nors = CustomData_add_layer(&mesh->fdata, CD_NORMAL, CD_CALLOC, NULL, mesh->totface);

View File

@@ -1328,7 +1328,7 @@ static int convert_exec(bContext *C, wmOperator *op)
/* re-tesselation doesn't happen automatic, calling like this is */
me= newob->data;
me->totface = mesh_recalcTesselation(&me->fdata, &me->ldata, &me->pdata, me->mvert, me->totface, me->totloop, me->totpoly, 0, 0);
me->totface = mesh_recalcTesselation(&me->fdata, &me->ldata, &me->pdata, me->mvert, me->totface, me->totloop, me->totpoly);
dm->release(dm);
object_free_modifiers(newob); /* after derivedmesh calls! */

View File

@@ -4811,15 +4811,6 @@ static int texture_paint_init(bContext *C, wmOperator *op)
me = pop->s.me;
/*recalc mesh tesselation so the face origindex values point
to the tesselation faces themselves, instead of polys*/
me->totface = mesh_recalcTesselation(&me->fdata, &me->ldata,
&me->pdata, me->mvert, me->totface, me->totloop, me->totpoly, 0, 1);
mesh_update_customdata_pointers(me);
/*force customdata update*/
makeDerivedMesh(scene, pop->ps.ob, NULL, CD_MASK_BAREMESH, 0);
/* Dont allow brush size below 2 */
if (pop->ps.brush && pop->ps.brush->size<=1)
pop->ps.brush->size = 2;

View File

@@ -1948,13 +1948,6 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, wmEvent *UNUSED
me= get_mesh(ob);
if(me==NULL || me->totface==0) return OPERATOR_PASS_THROUGH;
/*we can't assume mfaces have a correct origindex layer that indices to mpolys.
so instead we have to regenerate the tesselation faces altogether.*/
me->totface = mesh_recalcTesselation(&me->fdata, &me->ldata, &me->pdata,
me->mvert, me->totface, me->totloop, me->totpoly, 1, 0);
mesh_update_customdata_pointers(me);
makeDerivedMesh(scene, ob, NULL, CD_MASK_BAREMESH, 0);
/* if nothing was added yet, we make dverts and a vertex deform group */
if (!me->dvert) {
ED_vgroup_data_create(&me->id);
@@ -2420,14 +2413,7 @@ static void vpaint_build_poly_facemap(struct VPaintData *vd, Mesh *me,
vd->polyfacemap = BLI_memarena_alloc(vd->arena, sizeof(ListBase)*me->totpoly);
/*we can't assume mfaces have a correct origindex layer that indices to mpolys.
so instead we have to regenerate the tesselation faces altogether.*/
me->totface = mesh_recalcTesselation(&me->fdata, &me->ldata, &me->pdata,
me->mvert, me->totface, me->totloop, me->totpoly, 1, 0);
mesh_update_customdata_pointers(me);
makeDerivedMesh(scene, ob, NULL, CD_MASK_BAREMESH, 0);
origIndex = CustomData_get_layer(&me->fdata, CD_ORIGINDEX);
origIndex = CustomData_get_layer(&me->fdata, CD_POLYINDEX);
mf = me->mface;
if (!origIndex)

View File

@@ -512,6 +512,8 @@ static int draw_tface_mapped__set_draw(void *userData, int index)
MTFace mtf;
int matnr = me->mpoly[index].mat_nr;
BLI_assert(index >= 0 && index < me->totpoly);
if (mpoly && mpoly->flag&ME_HIDE) return 0;
memset(&mtf, 0, sizeof(mtf));

View File

@@ -76,7 +76,7 @@ typedef struct CustomData {
#define CD_MCOL 6
#define CD_ORIGINDEX 7
#define CD_NORMAL 8
#define CD_FLAGS 9
#define CD_POLYINDEX 9
#define CD_PROP_FLT 10
#define CD_PROP_INT 11
#define CD_PROP_STR 12
@@ -111,7 +111,7 @@ typedef struct CustomData {
#define CD_MASK_MCOL (1 << CD_MCOL)
#define CD_MASK_ORIGINDEX (1 << CD_ORIGINDEX)
#define CD_MASK_NORMAL (1 << CD_NORMAL)
#define CD_MASK_FLAGS (1 << CD_FLAGS)
#define CD_MASK_POLYINDEX (1 << CD_POLYINDEX)
#define CD_MASK_PROP_FLT (1 << CD_PROP_FLT)
#define CD_MASK_PROP_INT (1 << CD_PROP_INT)
#define CD_MASK_PROP_STR (1 << CD_PROP_STR)

View File

@@ -236,7 +236,7 @@ DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
ml->e += dm->numEdgeData;
}
CDDM_recalc_tesselation(cddm, 1);
CDDM_recalc_tesselation(cddm);
/*handle vgroup stuff*/
if ((mmd->flag & MOD_MIR_VGROUP) && CustomData_has_layer(&cddm->vertData, CD_MDEFORMVERT)) {

View File

@@ -98,7 +98,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob),
dm = copy = CDDM_copy(dm, 0);
}
CDDM_recalc_tesselation(dm, 1);
CDDM_recalc_tesselation(dm);
mf = dm->getTessFaceArray(dm);
of = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);

View File

@@ -722,7 +722,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
CDDM_calc_normals(result);
}
else {
CDDM_recalc_tesselation(result, 1);
CDDM_recalc_tesselation(result);
}
if (dm != odm) {