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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2009-12-09 16:37:19 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2009-12-09 16:37:19 +0300
commit9ea765e5d316ca6d2b15da2392e9da3643a856bb (patch)
tree7604b9d1dd06064432b9e56af4a7dedd669fec80
parentabae1e2ccf2bb16d4a436cdcbb17560252df7e8a (diff)
Sculpt Branch:
* Smooth brush works again for multires. * Optimal Display option for multires modifier, same as subsurf.
-rw-r--r--release/scripts/ui/properties_data_modifier.py3
-rw-r--r--source/blender/blenkernel/BKE_multires.h20
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.c27
-rw-r--r--source/blender/blenkernel/intern/multires.c67
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c6
-rw-r--r--source/blender/blenlib/BLI_pbvh.h9
-rw-r--r--source/blender/blenlib/intern/pbvh.c20
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c136
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h6
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c9
10 files changed, 236 insertions, 67 deletions
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; S<f->numVerts; S++)
- for (x=0; x<gridSize; x++)
- VertDataZero(FACE_getIECo(f, lvl, S, x));
+ if (FACE_getEdges(f)[S]->flags&Edge_eEffected)
+ for (x=0; x<gridSize; x++)
+ VertDataZero(FACE_getIECo(f, lvl, S, x));
for (S=0; S<f->numVerts; 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; x<gridSize-1; x++) {
- VertDataAdd(FACE_getIECo(f, lvl, S, x), FACE_getIFCo(f, lvl, S, x, 0));
- VertDataAdd(FACE_getIECo(f, lvl, prevS, x), FACE_getIFCo(f, lvl, S, 0, x));
+ if (FACE_getEdges(f)[S]->flags&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; x<gridSize-1; x++) {
int eI = gridSize-1-x;
- VertDataAdd(_edge_getCoVert(e, FACE_getVerts(f)[S], lvl, eI,vertDataSize), FACE_getIFCo(f, lvl, S, cornerIdx, x));
- if(x != 0)
- VertDataAdd(_edge_getCoVert(prevE, FACE_getVerts(f)[S], lvl, eI,vertDataSize), FACE_getIFCo(f, lvl, S, x, cornerIdx));
+ if (FACE_getEdges(f)[S]->flags&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; S<f->numVerts; S++)
- for (x=1; x<gridSize-1; x++)
- VertDataMulN(FACE_getIECo(f, lvl, S, x), 0.5f);
+ if (FACE_getEdges(f)[S]->flags&Edge_eEffected)
+ for (x=1; x<gridSize-1; x++)
+ VertDataMulN(FACE_getIECo(f, lvl, S, x), 0.5f);
for (S=0; S<f->numVerts; 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;
+}
- for(iteration = 0; iteration < 2; ++iteration) {
- #pragma omp parallel for private(n) schedule(static)
- for(n=0; n<totnode; n++) {
- PBVHVertexIter vd;
- SculptBrushTest test;
+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_undo_push_node(ss, nodes[n]);
- sculpt_brush_test_init(ss, &test);
+ sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->tree, nodes[n], vd, PBVH_ITER_UNIQUE) {
- if(sculpt_brush_test(&test, vd.co)) {
- float fade = tex_strength(ss, brush, vd.co, test.dist)*bstrength;
+ 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;
- 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;
+ sculpt_clip(sd, ss, data[x + y*gridsize].co, val);
}
}
- BLI_pbvh_vertex_iter_end;
+ }
+ }
+
+ #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; n<totnode; n++) {
+ sculpt_undo_push_node(ss, nodes[n]);
+
+ 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)