Partial fix for bug 30695, "Array broke crease, weird visibility and slowdown"
* Array modifier creates BMesh from DM; add missing CD_CREASE layer for edge creases. * With a modifier stack like mirror+subsurf+array, face normals were wrong. Fix by removing CD_NORMAL layer from CCGDM output. Previously the elements in this layer were simply copied, so they did not reflect subdivision correctly. * Minor style fixes in bmo_dupe.c. Issues not yet addressed: * Subsurf's optimal draw setting for hiding subdivision edges is not respected by the array output. * Slowdown issue; array modifier is much slower than in 2.62.
This commit is contained in:
@@ -49,6 +49,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
|
|||||||
MLoop *mloop, *ml;
|
MLoop *mloop, *ml;
|
||||||
BMVert *v, **vtable, **verts = NULL;
|
BMVert *v, **vtable, **verts = NULL;
|
||||||
BMEdge *e, **etable, **edges = NULL;
|
BMEdge *e, **etable, **edges = NULL;
|
||||||
|
float has_face_normals;
|
||||||
BMFace *f;
|
BMFace *f;
|
||||||
BMIter liter;
|
BMIter liter;
|
||||||
BLI_array_declare(verts);
|
BLI_array_declare(verts);
|
||||||
@@ -65,6 +66,9 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
|
|||||||
totedge = dm->getNumEdges(dm);
|
totedge = dm->getNumEdges(dm);
|
||||||
/* totface = dm->getNumPolys(dm); */ /* UNUSED */
|
/* totface = dm->getNumPolys(dm); */ /* UNUSED */
|
||||||
|
|
||||||
|
/* add crease layer */
|
||||||
|
BM_data_layer_add(bm, &bm->edata, CD_CREASE);
|
||||||
|
|
||||||
vtable = MEM_callocN(sizeof(void**) * totvert, "vert table in BMDM_Copy");
|
vtable = MEM_callocN(sizeof(void**) * totvert, "vert table in BMDM_Copy");
|
||||||
etable = MEM_callocN(sizeof(void**) * totedge, "edge table in BMDM_Copy");
|
etable = MEM_callocN(sizeof(void**) * totedge, "edge table in BMDM_Copy");
|
||||||
|
|
||||||
@@ -89,12 +93,16 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
|
|||||||
|
|
||||||
CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->head.data);
|
CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->head.data);
|
||||||
etable[i] = e;
|
etable[i] = e;
|
||||||
|
|
||||||
|
/* add crease */
|
||||||
|
BM_elem_float_data_set(&bm->edata, e, CD_CREASE, (float)me->crease / 255.0f);
|
||||||
}
|
}
|
||||||
MEM_freeN(medge);
|
MEM_freeN(medge);
|
||||||
|
|
||||||
/*do faces*/
|
/*do faces*/
|
||||||
mp = dm->getPolyArray(dm);
|
mp = dm->getPolyArray(dm);
|
||||||
mloop = dm->getLoopArray(dm);
|
mloop = dm->getLoopArray(dm);
|
||||||
|
has_face_normals = CustomData_has_layer(&dm->polyData, CD_NORMAL);
|
||||||
for (i = 0; i < dm->numPolyData; i++, mp++) {
|
for (i = 0; i < dm->numPolyData; i++, mp++) {
|
||||||
BMLoop *l;
|
BMLoop *l;
|
||||||
|
|
||||||
@@ -126,6 +134,13 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CustomData_to_bmesh_block(&dm->polyData, &bm->pdata, i, &f->head.data);
|
CustomData_to_bmesh_block(&dm->polyData, &bm->pdata, i, &f->head.data);
|
||||||
|
|
||||||
|
if (has_face_normals) {
|
||||||
|
float *fno;
|
||||||
|
|
||||||
|
fno = CustomData_bmesh_get(&bm->pdata, &f->head.data, CD_NORMAL);
|
||||||
|
copy_v3_v3(f->no, fno);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MEM_freeN(vtable);
|
MEM_freeN(vtable);
|
||||||
|
@@ -2945,6 +2945,9 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
|
|||||||
ccgSubSurf_getNumFinalFaces(ss)*4,
|
ccgSubSurf_getNumFinalFaces(ss)*4,
|
||||||
ccgSubSurf_getNumFinalFaces(ss));
|
ccgSubSurf_getNumFinalFaces(ss));
|
||||||
|
|
||||||
|
CustomData_free_layer_active(&ccgdm->dm.polyData, CD_NORMAL,
|
||||||
|
ccgdm->dm.numPolyData);
|
||||||
|
|
||||||
numTex = CustomData_number_of_layers(&ccgdm->dm.loopData, CD_MLOOPUV);
|
numTex = CustomData_number_of_layers(&ccgdm->dm.loopData, CD_MLOOPUV);
|
||||||
numCol = CustomData_number_of_layers(&ccgdm->dm.loopData, CD_MLOOPCOL);
|
numCol = CustomData_number_of_layers(&ccgdm->dm.loopData, CD_MLOOPCOL);
|
||||||
hasPCol = CustomData_has_layer(&ccgdm->dm.loopData, CD_PREVIEW_MLOOPCOL);
|
hasPCol = CustomData_has_layer(&ccgdm->dm.loopData, CD_PREVIEW_MLOOPCOL);
|
||||||
|
@@ -202,32 +202,33 @@ static void copy_mesh(BMOperator *op, BMesh *source, BMesh *target)
|
|||||||
vhash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "bmesh dupeops v");
|
vhash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "bmesh dupeops v");
|
||||||
ehash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "bmesh dupeops e");
|
ehash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "bmesh dupeops e");
|
||||||
|
|
||||||
|
/* duplicate flagged vertices */
|
||||||
for (v = BM_iter_new(&verts, source, BM_VERTS_OF_MESH, source); v; v = BM_iter_step(&verts)) {
|
for (v = BM_iter_new(&verts, source, BM_VERTS_OF_MESH, source); v; v = BM_iter_step(&verts)) {
|
||||||
if ( BMO_elem_flag_test(source, v, DUPE_INPUT) &&
|
if ( BMO_elem_flag_test(source, v, DUPE_INPUT) &&
|
||||||
!BMO_elem_flag_test(source, v, DUPE_DONE))
|
!BMO_elem_flag_test(source, v, DUPE_DONE))
|
||||||
{
|
{
|
||||||
BMIter iter;
|
BMIter iter;
|
||||||
int iso = 1;
|
int isolated = 1;
|
||||||
|
|
||||||
v2 = copy_vertex(source, v, target, vhash);
|
v2 = copy_vertex(source, v, target, vhash);
|
||||||
|
|
||||||
BM_ITER(f, &iter, source, BM_FACES_OF_VERT, v) {
|
BM_ITER(f, &iter, source, BM_FACES_OF_VERT, v) {
|
||||||
if (BMO_elem_flag_test(source, f, DUPE_INPUT)) {
|
if (BMO_elem_flag_test(source, f, DUPE_INPUT)) {
|
||||||
iso = 0;
|
isolated = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iso) {
|
if (isolated) {
|
||||||
BM_ITER(e, &iter, source, BM_EDGES_OF_VERT, v) {
|
BM_ITER(e, &iter, source, BM_EDGES_OF_VERT, v) {
|
||||||
if (BMO_elem_flag_test(source, e, DUPE_INPUT)) {
|
if (BMO_elem_flag_test(source, e, DUPE_INPUT)) {
|
||||||
iso = 0;
|
isolated = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iso) {
|
if (isolated) {
|
||||||
BMO_slot_map_ptr_insert(source, op, "isovertmap", v, v2);
|
BMO_slot_map_ptr_insert(source, op, "isovertmap", v, v2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user