diff --git a/release/scripts/ui/properties_data_modifier.py b/release/scripts/ui/properties_data_modifier.py index 54a4defb676..8194027bae6 100644 --- a/release/scripts/ui/properties_data_modifier.py +++ b/release/scripts/ui/properties_data_modifier.py @@ -438,6 +438,7 @@ class DATA_PT_modifiers(DataButtonsPanel): col.prop(md, "levels", text="Preview") col.prop(md, "sculpt_levels", text="Sculpt") col.prop(md, "render_levels", text="Render") + col.prop(md, "optimal_display") if wide_ui: col = split.column() @@ -604,7 +605,7 @@ class DATA_PT_modifiers(DataButtonsPanel): if wide_ui: col = split.column() col.label(text="Options:") - col.prop(md, "optimal_draw", text="Optimal Display") + col.prop(md, "optimal_display") def SURFACE(self, layout, ob, md, wide_ui): layout.label(text="See Fields panel.") diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h index 53ead3a5eda..ff320bc7d25 100644 --- a/source/blender/blenkernel/BKE_multires.h +++ b/source/blender/blenkernel/BKE_multires.h @@ -27,24 +27,22 @@ * ***** END GPL LICENSE BLOCK ***** */ +#ifndef BKE_MULTIRES_H +#define BKE_MULTIRES_H + struct DerivedMesh; struct Mesh; struct MFace; +struct Multires; struct MultiresModifierData; struct Object; -typedef struct MultiresSubsurf { - struct MultiresModifierData *mmd; - struct Object *ob; - int local_mmd; -} MultiresSubsurf; - void multires_mark_as_modified(struct Object *ob); void multires_force_update(struct Object *ob); -struct DerivedMesh *multires_dm_create_from_derived(struct MultiresModifierData*, int local_mmd, struct DerivedMesh*, - struct Object *, int, int); +struct DerivedMesh *multires_dm_create_from_derived(struct MultiresModifierData*, + int local_mmd, struct DerivedMesh*, struct Object *, int, int); struct MultiresModifierData *find_multires_modifier(struct Object *ob); void multiresModifier_join(struct Object *); @@ -53,7 +51,11 @@ void multiresModifier_subdivide(struct MultiresModifierData *mmd, struct Object int updateblock, int simple); int multiresModifier_reshape(struct MultiresModifierData *mmd, struct Object *dst, struct Object *src); +void multires_stitch_grids(struct Object *); + /* Related to the old multires */ -struct Multires; void multires_load_old(struct DerivedMesh *, struct Multires *); void multires_free(struct Multires*); + +#endif + diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c index cc2bd531fe6..4bd0586c592 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.c +++ b/source/blender/blenkernel/intern/CCGSubSurf.c @@ -2228,8 +2228,9 @@ CCGError ccgSubSurf_stitchFaces(CCGSubSurf *ss, int lvl, CCGFace **effectedF, in VertDataZero(FACE_getCenterData(f)); for (S=0; SnumVerts; S++) - for (x=0; xflags&Edge_eEffected) + for (x=0; xnumVerts; S++) { int prevS = (S+f->numVerts-1)%f->numVerts; @@ -2237,18 +2238,23 @@ CCGError ccgSubSurf_stitchFaces(CCGSubSurf *ss, int lvl, CCGFace **effectedF, in CCGEdge *prevE = FACE_getEdges(f)[prevS]; VertDataAdd(FACE_getCenterData(f), FACE_getIFCo(f, lvl, S, 0, 0)); - VertDataAdd(VERT_getCo(FACE_getVerts(f)[S], lvl), FACE_getIFCo(f, lvl, S, cornerIdx, cornerIdx)); + if (FACE_getVerts(f)[S]->flags&Vert_eEffected) + VertDataAdd(VERT_getCo(FACE_getVerts(f)[S], lvl), FACE_getIFCo(f, lvl, S, cornerIdx, cornerIdx)); for (x=1; xflags&Edge_eEffected) + VertDataAdd(FACE_getIECo(f, lvl, S, x), FACE_getIFCo(f, lvl, S, x, 0)); + if (FACE_getEdges(f)[prevS]->flags&Edge_eEffected) + VertDataAdd(FACE_getIECo(f, lvl, prevS, x), FACE_getIFCo(f, lvl, S, 0, x)); } for (x=0; xflags&Edge_eEffected) + VertDataAdd(_edge_getCoVert(e, FACE_getVerts(f)[S], lvl, eI,vertDataSize), FACE_getIFCo(f, lvl, S, cornerIdx, x)); + if (FACE_getEdges(f)[prevS]->flags&Edge_eEffected) + if(x != 0) + VertDataAdd(_edge_getCoVert(prevE, FACE_getVerts(f)[S], lvl, eI,vertDataSize), FACE_getIFCo(f, lvl, S, x, cornerIdx)); } } } @@ -2276,8 +2282,9 @@ CCGError ccgSubSurf_stitchFaces(CCGSubSurf *ss, int lvl, CCGFace **effectedF, in VertDataMulN(FACE_getCenterData(f), 1.0f/f->numVerts); for (S=0; SnumVerts; S++) - for (x=1; xflags&Edge_eEffected) + for (x=1; xnumVerts; S++) { int prevS = (S+f->numVerts-1)%f->numVerts; diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 69659db3ba7..8a76d659d5f 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -39,6 +39,7 @@ #include "BLI_math.h" #include "BLI_blenlib.h" +#include "BLI_pbvh.h" #include "BKE_btex.h" #include "BKE_cdderivedmesh.h" @@ -60,8 +61,8 @@ /* MULTIRES MODIFIER */ static const int multires_max_levels = 13; -static const int multires_grid_tot[] = {1, 4, 9, 25, 81, 289, 1089, 4225, 16641, 66049, 263169, 1050625, 4198401, 16785409}; -static const int multires_side_tot[] = {1, 2, 3, 5, 9, 17, 33, 65, 129, 257, 513, 1025, 2049, 4097}; +static const int multires_grid_tot[] = {0, 4, 9, 25, 81, 289, 1089, 4225, 16641, 66049, 263169, 1050625, 4198401, 16785409}; +static const int multires_side_tot[] = {0, 2, 3, 5, 9, 17, 33, 65, 129, 257, 513, 1025, 2049, 4097}; static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, int invert, int add, DMGridData **oldGridData, int totlvl); @@ -307,7 +308,7 @@ static DerivedMesh *multires_dm_create_local(Object *ob, DerivedMesh *dm, int lv return multires_dm_create_from_derived(&mmd, 1, dm, ob, 0, 0); } -static DerivedMesh *subsurf_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int simple) +static DerivedMesh *subsurf_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int simple, int optimal) { SubsurfModifierData smd; @@ -316,6 +317,8 @@ static DerivedMesh *subsurf_dm_create_local(Object *ob, DerivedMesh *dm, int lvl smd.flags |= eSubsurfModifierFlag_SubsurfUv; if(simple) smd.subdivType = ME_SIMPLE_SUBSURF; + if(optimal) + smd.flags |= eSubsurfModifierFlag_ControlEdges; return subsurf_make_derived_from_derived(dm, &smd, 0, NULL, 0, 0); } @@ -363,7 +366,7 @@ void multiresModifier_subdivide(MultiresModifierData *mmd, Object *ob, int updat /* create subsurf DM from original mesh at high level */ cddm = CDDM_from_mesh(me, NULL); - highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple); + highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple, 0); /* create multires DM from original mesh at low level */ lowdm = multires_dm_create_local(ob, cddm, lvl, lvl, simple); @@ -551,7 +554,7 @@ static void multiresModifier_update(DerivedMesh *dm) /* create subsurf DM from original mesh at high level */ cddm = CDDM_from_mesh(me, NULL); - highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple); + highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple, 0); /* create multires DM from original mesh and displacements */ lowdm = multires_dm_create_local(ob, cddm, lvl, totlvl, mmd->simple); @@ -602,7 +605,7 @@ static void multiresModifier_update(DerivedMesh *dm) DerivedMesh *cddm, *subdm; cddm = CDDM_from_mesh(me, NULL); - subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple); + subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0); cddm->release(cddm); multiresModifier_disp_run(dm, me, 1, 0, subdm->getGridData(subdm), mmd->totlvl); @@ -629,6 +632,25 @@ void multires_force_update(Object *ob) } } +void multires_stitch_grids(Object *ob) +{ + /* utility for smooth brush */ + if(ob && ob->derivedFinal) { + CCGDerivedMesh *ccgdm = (CCGDerivedMesh*)ob->derivedFinal; + CCGFace **faces; + int totface; + + if(ccgdm->pbvh) { + BLI_pbvh_get_grid_updates(ccgdm->pbvh, 0, (void***)&faces, &totface); + + if(totface) { + ccgSubSurf_stitchFaces(ccgdm->ss, 0, faces, totface); + MEM_freeN(faces); + } + } + } +} + struct DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd, int local_mmd, DerivedMesh *dm, Object *ob, int useRenderParams, int isFinalCalc) { @@ -642,7 +664,8 @@ struct DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd, i if(lvl == 0) return dm; - result = subsurf_dm_create_local(ob, dm, lvl, 0); + result = subsurf_dm_create_local(ob, dm, lvl, + mmd->simple, mmd->flags & eMultiresModifierFlag_ControlEdges); if(!local_mmd) { ccgdm = (CCGDerivedMesh*)result; @@ -680,6 +703,36 @@ struct DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd, i /**** Old Multires code **** ***************************/ +#if 0 +static void mdisp_copy_grid(float (*new)[3], int newstride, float (*old)[3], int oldstride, int xoff, int yoff, int xsize, int ysize) +{ + int x, y; + + for(y = 0; y < ysize; ++y) + for(x = 0; x < xsize; ++x) + copy_v3_v3(disps[x + y*side], mdisp->disps[(x + xoffs) + (y + yoffs)*oldside]); + +} + +static void mdisps_convert(MFace *mface, MDisps *mdisp, int lvl) +{ + int side = multires_side_tot[lvl]; + int nvert = (mface->v4)? 4: 3; + int totdisp = multires_grid_tot[lvl]*nvert; + int x, y; + float (*disps)[3]; + + disps = MEM_callocN(sizeof(float) * 3 * totdisp, "multires disps"); + + + +static const int multires_max_levels = 13; +static const int multires_grid_tot[] = {1, 4, 9, 25, 81, 289, 1089, 4225, 16641, 66049, 263169, 1050625, 4198401, 16785409}; +static const int multires_side_tot[] = {1, 2, 3, 5, 9, 17, 33, 65, 129, 257, 513, 1025, 2049, 4097}; + +} +#endif + /* Does not actually free lvl itself */ static void multires_free_level(MultiresLevel *lvl) { diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index c9d84670044..f6abedda2b6 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -1235,7 +1235,7 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes) CCGFace **faces; int totface; - BLI_pbvh_get_grid_updates(ccgdm->pbvh, (void***)&faces, &totface); + BLI_pbvh_get_grid_updates(ccgdm->pbvh, 1, (void***)&faces, &totface); if(totface) { ccgSubSurf_updateFromFaces(ss, 0, faces, totface); ccgSubSurf_updateNormals(ss, faces, totface); @@ -2155,8 +2155,8 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) numGrids = ccgDM_getNumGrids(dm); ccgdm->pbvh = BLI_pbvh_new(); - BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, numGrids, gridSize, - (void**)ccgdm->gridFaces); + BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, + numGrids, gridSize, (void**)ccgdm->gridFaces); } else if(ob->type == OB_MESH) { Mesh *me= ob->data; diff --git a/source/blender/blenlib/BLI_pbvh.h b/source/blender/blenlib/BLI_pbvh.h index 5c5277dc091..e1e733c91df 100644 --- a/source/blender/blenlib/BLI_pbvh.h +++ b/source/blender/blenlib/BLI_pbvh.h @@ -27,6 +27,7 @@ struct MFace; struct MVert; +struct DMGridAdjacency; struct DMGridData; struct PBVH; struct PBVHNode; @@ -47,7 +48,8 @@ typedef void (*BLI_pbvh_HitCallback)(PBVHNode *node, void *data); PBVH *BLI_pbvh_new(void); void BLI_pbvh_build_mesh(PBVH *bvh, struct MFace *faces, struct MVert *verts, int totface, int totvert); -void BLI_pbvh_build_grids(PBVH *bvh, struct DMGridData **grids, int totgrid, +void BLI_pbvh_build_grids(PBVH *bvh, struct DMGridData **grids, + struct DMGridAdjacency *gridadj, int totgrid, int gridsize, void **gridfaces); void BLI_pbvh_free(PBVH *bvh); @@ -94,7 +96,8 @@ typedef enum { void BLI_pbvh_node_mark_update(PBVHNode *node); void BLI_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node, - int **grid_indices, int *totgrid, int *maxgrid, int *gridsize); + int **grid_indices, int *totgrid, int *maxgrid, int *gridsize, + struct DMGridData ***griddata, struct DMGridAdjacency **gridadj); void BLI_pbvh_node_num_verts(PBVH *bvh, PBVHNode *node, int *uniquevert, int *totvert); @@ -105,7 +108,7 @@ void BLI_pbvh_node_get_original_BB(PBVHNode *node, float bb_min[3], float bb_max void BLI_pbvh_update(PBVH *bvh, int flags, float (*face_nors)[3]); void BLI_pbvh_redraw_BB(PBVH *bvh, float bb_min[3], float bb_max[3]); -void BLI_pbvh_get_grid_updates(PBVH *bvh, void ***gridfaces, int *totface); +void BLI_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *totface); /* Vertex Iterator */ diff --git a/source/blender/blenlib/intern/pbvh.c b/source/blender/blenlib/intern/pbvh.c index 3aa0f43553f..960888260ce 100644 --- a/source/blender/blenlib/intern/pbvh.c +++ b/source/blender/blenlib/intern/pbvh.c @@ -114,6 +114,7 @@ struct PBVH { /* Grid Data */ DMGridData **grids; + DMGridAdjacency *gridadj; void **gridfaces; int totgrid; int gridsize; @@ -510,14 +511,15 @@ void BLI_pbvh_build_mesh(PBVH *bvh, MFace *faces, MVert *verts, int totface, int } /* Do a full rebuild with on Grids data structure */ -void BLI_pbvh_build_grids(PBVH *bvh, DMGridData **grids, int totgrid, - int gridsize, void **gridfaces) +void BLI_pbvh_build_grids(PBVH *bvh, DMGridData **grids, DMGridAdjacency *gridadj, + int totgrid, int gridsize, void **gridfaces) { BBC *prim_bbc = NULL; BB cb; int i, j; bvh->grids= grids; + bvh->gridadj= gridadj; bvh->gridfaces= gridfaces; bvh->totgrid= totgrid; bvh->gridsize= gridsize; @@ -948,7 +950,7 @@ void BLI_pbvh_redraw_BB(PBVH *bvh, float bb_min[3], float bb_max[3]) copy_v3_v3(bb_max, bb.bmax); } -void BLI_pbvh_get_grid_updates(PBVH *bvh, void ***gridfaces, int *totface) +void BLI_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *totface) { PBVHIter iter; PBVHNode *node; @@ -965,10 +967,12 @@ void BLI_pbvh_get_grid_updates(PBVH *bvh, void ***gridfaces, int *totface) if(node->flag & PBVH_UpdateNormals) { for(i = 0; i < node->totprim; ++i) { face= bvh->gridfaces[node->prim_indices[i]]; - BLI_ghash_insert(map, face, face); + if(!BLI_ghash_lookup(map, face)) + BLI_ghash_insert(map, face, face); } - node->flag &= ~PBVH_UpdateNormals; + if(clear) + node->flag &= ~PBVH_UpdateNormals; } } @@ -1021,19 +1025,23 @@ void BLI_pbvh_node_num_verts(PBVH *bvh, PBVHNode *node, int *uniquevert, int *to } } -void BLI_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node, int **grid_indices, int *totgrid, int *maxgrid, int *gridsize) +void BLI_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node, int **grid_indices, int *totgrid, int *maxgrid, int *gridsize, DMGridData ***griddata, DMGridAdjacency **gridadj) { if(bvh->grids) { if(grid_indices) *grid_indices= node->prim_indices; if(totgrid) *totgrid= node->totprim; if(maxgrid) *maxgrid= bvh->totgrid; if(gridsize) *gridsize= bvh->gridsize; + if(griddata) *griddata= bvh->grids; + if(gridadj) *gridadj= bvh->gridadj; } else { if(grid_indices) *grid_indices= NULL; if(totgrid) *totgrid= 0; if(maxgrid) *maxgrid= 0; if(gridsize) *gridsize= 0; + if(griddata) *griddata= NULL; + if(gridadj) *gridadj= NULL; } } diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index d67f13f1537..c715dc97cde 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -415,7 +415,8 @@ static SculptUndoNode *sculpt_undo_push_node(SculptSession *ss, PBVHNode *node) unode->node= node; BLI_pbvh_node_num_verts(ss->tree, node, &totvert, &allvert); - BLI_pbvh_node_get_grids(ss->tree, node, &grids, &totgrid, &maxgrid, &gridsize); + BLI_pbvh_node_get_grids(ss->tree, node, &grids, &totgrid, + &maxgrid, &gridsize, NULL, NULL); unode->totvert= totvert; /* we will use this while sculpting, is mapalloc slow to access then? */ @@ -795,9 +796,9 @@ static void calc_area_normal(Sculpt *sd, SculptSession *ss, float area_normal[3] BLI_pbvh_vertex_iter_end; } + #pragma omp critical { /* we sum per node and add together later for threads */ - #pragma omp critical add_v3_v3v3(out, out, nout); add_v3_v3v3(out_flip, out_flip, nout_flip); } @@ -903,43 +904,128 @@ static void neighbor_average(SculptSession *ss, float avg[3], const int vert) copy_v3_v3(avg, ss->mvert[vert].co); } -static void do_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int totnode) +static void do_mesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node) { Brush *brush = paint_brush(&sd->paint); float bstrength= ss->cache->bstrength; - int iteration, n; + PBVHVertexIter vd; + SculptBrushTest test; + + sculpt_brush_test_init(ss, &test); - /* XXX not working for multires yet */ - if(!ss->fmap) - return; + BLI_pbvh_vertex_iter_begin(ss->tree, node, vd, PBVH_ITER_UNIQUE) { + if(sculpt_brush_test(&test, vd.co)) { + float fade = tex_strength(ss, brush, vd.co, test.dist)*bstrength; + float avg[3], val[3]; + + neighbor_average(ss, avg, vd.vert_indices[vd.i]); + val[0] = vd.co[0]+(avg[0]-vd.co[0])*fade; + val[1] = vd.co[1]+(avg[1]-vd.co[1])*fade; + val[2] = vd.co[2]+(avg[2]-vd.co[2])*fade; + + sculpt_clip(sd, ss, vd.co, val); + if(vd.mvert) vd.mvert->flag |= ME_VERT_PBVH_UPDATE; + } + } + BLI_pbvh_vertex_iter_end; +} + +static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node) +{ + Brush *brush = paint_brush(&sd->paint); + SculptBrushTest test; + DMGridData **griddata, *data; + DMGridAdjacency *gridadj, *adj; + float bstrength= ss->cache->bstrength; + float co[3], (*tmpgrid)[3]; + int v1, v2, v3, v4; + int *grid_indices, totgrid, gridsize, i, x, y; + + sculpt_brush_test_init(ss, &test); + + BLI_pbvh_node_get_grids(ss->tree, node, &grid_indices, &totgrid, + NULL, &gridsize, &griddata, &gridadj); + + #pragma omp critical + tmpgrid= MEM_mallocN(sizeof(float)*3*gridsize*gridsize, "tmpgrid"); + + for(i = 0; i < totgrid; ++i) { + data = griddata[grid_indices[i]]; + adj = &gridadj[grid_indices[i]]; + + memset(tmpgrid, 0, sizeof(float)*3*gridsize*gridsize); + + /* average grid values */ + for(y = 0; y < gridsize-1; ++y) { + for(x = 0; x < gridsize-1; ++x) { + v1 = x + y*gridsize; + v2 = (x + 1) + y*gridsize; + v3 = (x + 1) + (y + 1)*gridsize; + v4 = x + (y + 1)*gridsize; + + cent_quad_v3(co, data[v1].co, data[v2].co, data[v3].co, data[v4].co); + mul_v3_fl(co, 0.25f); + + add_v3_v3(tmpgrid[v1], co); + add_v3_v3(tmpgrid[v2], co); + add_v3_v3(tmpgrid[v3], co); + add_v3_v3(tmpgrid[v4], co); + } + } + + /* blend with existing coordinates */ + for(y = 0; y < gridsize; ++y) { + for(x = 0; x < gridsize; ++x) { + if(x == 0 && adj->index[0] == -1) continue; + if(x == gridsize - 1 && adj->index[2] == -1) continue; + if(y == 0 && adj->index[3] == -1) continue; + if(y == gridsize - 1 && adj->index[1] == -1) continue; + + copy_v3_v3(co, data[x + y*gridsize].co); + + if(sculpt_brush_test(&test, co)) { + float fade = tex_strength(ss, brush, co, test.dist)*bstrength; + float avg[3], val[3]; + + copy_v3_v3(avg, tmpgrid[x + y*gridsize]); + if(x == 0 || x == gridsize - 1) + mul_v3_fl(avg, 2.0f); + if(y == 0 || y == gridsize - 1) + mul_v3_fl(avg, 2.0f); + + val[0] = co[0]+(avg[0]-co[0])*fade; + val[1] = co[1]+(avg[1]-co[1])*fade; + val[2] = co[2]+(avg[2]-co[2])*fade; + + sculpt_clip(sd, ss, data[x + y*gridsize].co, val); + } + } + } + } + + #pragma omp critical + MEM_freeN(tmpgrid); +} + +static void do_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int totnode) +{ + int iteration, n; for(iteration = 0; iteration < 2; ++iteration) { #pragma omp parallel for private(n) schedule(static) for(n=0; ntree, nodes[n], vd, PBVH_ITER_UNIQUE) { - if(sculpt_brush_test(&test, vd.co)) { - float fade = tex_strength(ss, brush, vd.co, test.dist)*bstrength; - float avg[3], val[3]; - - neighbor_average(ss, avg, vd.vert_indices[vd.i]); - val[0] = vd.co[0]+(avg[0]-vd.co[0])*fade; - val[1] = vd.co[1]+(avg[1]-vd.co[1])*fade; - val[2] = vd.co[2]+(avg[2]-vd.co[2])*fade; - - sculpt_clip(sd, ss, vd.co, val); - if(vd.mvert) vd.mvert->flag |= ME_VERT_PBVH_UPDATE; - } - } - BLI_pbvh_vertex_iter_end; + if(ss->fmap) + do_mesh_smooth_brush(sd, ss, nodes[n]); + else + do_multires_smooth_brush(sd, ss, nodes[n]); BLI_pbvh_node_mark_update(nodes[n]); } + + if(!ss->fmap) + multires_stitch_grids(ss->ob); } } diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 33130c6732f..c599c8a7e0f 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -586,9 +586,13 @@ typedef struct MultiresModifierData { ModifierData modifier; char lvl, sculptlvl, renderlvl, totlvl; - char simple, pad[3]; + char simple, flags, pad[2]; } MultiresModifierData; +typedef enum { + eMultiresModifierFlag_ControlEdges = (1<<0), +} MultiresModifierFlag; + typedef struct FluidsimModifierData { ModifierData modifier; diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index dedd072011d..cefaf2d7535 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -534,9 +534,9 @@ static void rna_def_modifier_subsurf(BlenderRNA *brna) RNA_def_property_ui_range(prop, 0, 6, 1, 0); RNA_def_property_ui_text(prop, "Render Levels", "Number of subdivisions to perform when rendering."); - prop= RNA_def_property(srna, "optimal_draw", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "optimal_display", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", eSubsurfModifierFlag_ControlEdges); - RNA_def_property_ui_text(prop, "Optimal Draw", "Skip drawing/rendering of interior subdivided edges"); + RNA_def_property_ui_text(prop, "Optimal Display", "Skip drawing/rendering of interior subdivided edges"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "subsurf_uv", PROP_BOOLEAN, PROP_NONE); @@ -583,6 +583,11 @@ static void rna_def_modifier_multires(BlenderRNA *brna) RNA_def_property_boolean_funcs(prop, "rna_MultiresModifier_external_get", "rna_MultiresModifier_external_set"); RNA_def_property_editable_func(prop, "rna_MultiresModifier_external_editable"); RNA_def_property_ui_text(prop, "External", "Store multires displacements outside the .blend file, to save memory."); + + prop= RNA_def_property(srna, "optimal_display", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flags", eMultiresModifierFlag_ControlEdges); + RNA_def_property_ui_text(prop, "Optimal Display", "Skip drawing/rendering of interior subdivided edges"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); } static void rna_def_modifier_lattice(BlenderRNA *brna)