dyntopo: don't allocate tessfaces while sculpting

Tessellation data isn't used for drawing or sculpting.

This frees up some memory ~approx 10% in own tests.
Also slight spee-up since it avoids calculating it in the first place.
This commit is contained in:
Campbell Barton 2015-04-16 04:14:01 +10:00
parent 7f4b6a345e
commit 6675fd6b52
7 changed files with 35 additions and 21 deletions

View File

@ -121,6 +121,7 @@ typedef enum {
} PBVHType;
PBVHType BKE_pbvh_type(const PBVH *bvh);
bool BKE_pbvh_has_faces(const PBVH *bvh);
/* Get the PBVH root's bounding box */
void BKE_pbvh_bounding_box(const PBVH *bvh, float min[3], float max[3]);

View File

@ -1939,7 +1939,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
DM_calc_loop_normals(finaldm, do_loop_normals, loop_normals_split_angle);
}
{
if (sculpt_dyntopo == false) {
DM_ensure_tessface(finaldm);
/* without this, drawing ngon tri's faces will show ugly tessellated face
@ -2348,7 +2348,7 @@ static CustomDataMask object_get_datamask(const Scene *scene, Object *ob)
if (ob == actob) {
/* check if we need tfaces & mcols due to face select or texture paint */
if (BKE_paint_select_face_test(ob) || (ob->mode & OB_MODE_TEXTURE_PAINT)) {
if ((ob->mode & OB_MODE_TEXTURE_PAINT) || BKE_paint_select_face_test(ob)) {
mask |= CD_MASK_MTFACE | CD_MASK_MCOL;
}

View File

@ -470,7 +470,7 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm,
int a;
if (cddm->pbvh && cddm->pbvh_draw) {
if (dm->numTessFaceData) {
if (BKE_pbvh_has_faces(cddm->pbvh)) {
float (*face_nors)[3] = CustomData_get_layer(&dm->faceData, CD_NORMAL);
BKE_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors,
@ -527,7 +527,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
* (the same as it'll display without UV maps in textured view)
*/
if (cddm->pbvh && cddm->pbvh_draw && BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH) {
if (dm->numTessFaceData) {
if (BKE_pbvh_has_faces(cddm->pbvh)) {
GPU_set_tpage(NULL, false, false);
BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, false);
}
@ -912,7 +912,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
* works fine for matcap
*/
if (cddm->pbvh && cddm->pbvh_draw && BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH) {
if (dm->numTessFaceData) {
if (BKE_pbvh_has_faces(cddm->pbvh)) {
setMaterial(1, &gattribs);
BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, false);
}
@ -1246,7 +1246,7 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
* works fine for matcap
*/
if (cddm->pbvh && cddm->pbvh_draw && BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH) {
if (dm->numTessFaceData) {
if (BKE_pbvh_has_faces(cddm->pbvh)) {
setMaterial(userData, 1, &gattribs);
BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, false);
}

View File

@ -566,13 +566,9 @@ void paint_calculate_rake_rotation(UnifiedPaintSettings *ups, Brush *brush, cons
void BKE_sculptsession_free_deformMats(SculptSession *ss)
{
if (ss->orig_cos) MEM_freeN(ss->orig_cos);
if (ss->deform_cos) MEM_freeN(ss->deform_cos);
if (ss->deform_imats) MEM_freeN(ss->deform_imats);
ss->orig_cos = NULL;
ss->deform_cos = NULL;
ss->deform_imats = NULL;
MEM_SAFE_FREE(ss->orig_cos);
MEM_SAFE_FREE(ss->deform_cos);
MEM_SAFE_FREE(ss->deform_imats);
}
/* Write out the sculpt dynamic-topology BMesh to the Mesh */
@ -772,7 +768,12 @@ void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
}
/* BMESH ONLY --- at some point we should move sculpt code to use polygons only - but for now it needs tessfaces */
BKE_mesh_tessface_ensure(me);
if (ss->bm) {
BKE_mesh_tessface_clear(me);
}
else {
BKE_mesh_tessface_ensure(me);
}
if (!mmd) ss->kb = BKE_keyblock_from_object(ob);
else ss->kb = NULL;

View File

@ -943,6 +943,7 @@ static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes,
int n;
if (bvh->type == PBVH_BMESH) {
BLI_assert(face_nors == NULL);
pbvh_bmesh_normals_update(nodes, totnode);
return;
}
@ -1280,6 +1281,16 @@ PBVHType BKE_pbvh_type(const PBVH *bvh)
return bvh->type;
}
bool BKE_pbvh_has_faces(const PBVH *bvh)
{
if (bvh->type == PBVH_BMESH) {
return (bvh->bm->totface != 0);
}
else {
return (bvh->totprim != 0);
}
}
void BKE_pbvh_bounding_box(const PBVH *bvh, float min[3], float max[3])
{
if (bvh->totnode) {

View File

@ -1762,7 +1762,7 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
ccgdm_pbvh_update(ccgdm);
if (ccgdm->pbvh && ccgdm->multires.mmd && !fast) {
if (dm->numTessFaceData) {
if (BKE_pbvh_has_faces(ccgdm->pbvh)) {
BKE_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL,
setMaterial, false);
glShadeModel(GL_FLAT);

View File

@ -3912,7 +3912,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
#endif
Mesh *me = ob->data;
eWireDrawMode draw_wire = OBDRAW_WIRE_OFF;
int /* totvert,*/ totedge, totface;
bool /* no_verts,*/ no_edges, no_faces;
DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
const bool is_obact = (ob == OBACT);
int draw_flags = (is_obact && BKE_paint_select_face_test(ob)) ? DRAW_FACE_SELECT : 0;
@ -3935,8 +3935,9 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
draw_wire = OBDRAW_WIRE_ON_DEPTH; /* draw wire after solid using zoffset and depth buffer adjusment */
}
totedge = dm->getNumEdges(dm);
totface = dm->getNumTessFaces(dm);
/* check polys instead of tessfaces because of dyntopo where tessfaces don't exist */
no_edges = (dm->getNumEdges(dm) == 0);
no_faces = (dm->getNumPolys(dm) == 0);
/* vertexpaint, faceselect wants this, but it doesnt work for shaded? */
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
@ -3945,14 +3946,14 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
if (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_WIRE) == 0)
draw_bounding_volume(ob, ob->boundtype);
}
else if ((totface == 0 && totedge == 0) ||
else if ((no_faces && no_edges) ||
((!is_obact || (ob->mode == OB_MODE_OBJECT)) && object_is_halo(scene, ob)))
{
glPointSize(1.5);
dm->drawVerts(dm);
glPointSize(1.0);
}
else if (dt == OB_WIRE || totface == 0) {
else if ((dt == OB_WIRE) || no_faces) {
draw_wire = OBDRAW_WIRE_ON; /* draw wire only, no depth buffer stuff */
}
else if (((is_obact && ob->mode & OB_MODE_TEXTURE_PAINT)) ||
@ -4146,7 +4147,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
glDepthMask(0); /* disable write in zbuffer, selected edge wires show better */
}
dm->drawEdges(dm, (dt == OB_WIRE || totface == 0), (ob->dtx & OB_DRAW_ALL_EDGES) != 0);
dm->drawEdges(dm, ((dt == OB_WIRE) || no_faces), (ob->dtx & OB_DRAW_ALL_EDGES) != 0);
if (dt != OB_WIRE && (draw_wire == OBDRAW_WIRE_ON_DEPTH)) {
glDepthMask(1);