diff options
Diffstat (limited to 'source/blender/editors/sculpt_paint/sculpt.c')
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt.c | 146 |
1 files changed, 137 insertions, 9 deletions
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 64af39ea497..01a2ff3fdee 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -91,6 +91,7 @@ #include "RE_shader_ext.h" /*for multitex_ext*/ #include "GPU_draw.h" +#include "gpu_buffers.h" #include <math.h> #include <stdlib.h> @@ -304,21 +305,35 @@ static void calc_area_normal(Sculpt *sd, SculptSession *ss, float out[3], const static void do_draw_brush(Sculpt *sd, SculptSession *ss, const ListBase* active_verts) { float area_normal[3]; + int j; ActiveData *node= active_verts->first; + float* buffer; calc_area_normal(sd, ss, area_normal, active_verts); + buffer = ss->drawobject!=0?(float *)GPU_buffer_lock( ss->drawobject->vertices ):0; + while(node){ float *co= ss->mvert[node->Index].co; const float val[3]= {co[0]+area_normal[0]*ss->cache->radius*node->Fade*ss->cache->scale[0], co[1]+area_normal[1]*ss->cache->radius*node->Fade*ss->cache->scale[1], co[2]+area_normal[2]*ss->cache->radius*node->Fade*ss->cache->scale[2]}; - + + if( buffer != 0 ) { + IndexLink *cur = &ss->drawobject->indices[node->Index]; + while( cur != 0 && cur->element != -1 ) { + sculpt_clip(sd, ss, &buffer[cur->element*3], val); + cur = cur->next; + } + } + sculpt_clip(sd, ss, co, val); - + node= node->next; } + if( buffer != 0 ) + GPU_buffer_unlock( ss->drawobject->vertices ); } /* For the smooth brush, uses the neighboring vertices around vert to calculate @@ -368,6 +383,7 @@ static void neighbor_average(SculptSession *ss, float avg[3], const int vert) static void do_smooth_brush(Sculpt *s, SculptSession *ss, const ListBase* active_verts) { ActiveData *node= active_verts->first; + float *buffer = ss->drawobject!=0?(float *)GPU_buffer_lock( ss->drawobject->vertices ):0; int i; for(i = 0; i < 2; ++i) { @@ -380,24 +396,45 @@ static void do_smooth_brush(Sculpt *s, SculptSession *ss, const ListBase* active val[1] = co[1]+(avg[1]-co[1])*node->Fade; val[2] = co[2]+(avg[2]-co[2])*node->Fade; - sculpt_clip(s, ss, co, val); + sculpt_clip(s, ss, co, val); + if( buffer != 0 ) { + IndexLink *cur = &ss->drawobject->indices[node->Index]; + while( cur != 0 && cur->element != -1 ) { + sculpt_clip(s, ss, &buffer[cur->element*3], val); + cur = cur->next; + } + } node= node->next; } } + if( buffer != 0 ) + GPU_buffer_unlock( ss->drawobject->vertices ); } static void do_pinch_brush(Sculpt *s, SculptSession *ss, const ListBase* active_verts) { ActiveData *node= active_verts->first; + float *buffer = ss->drawobject!=0?(float *)GPU_buffer_lock( ss->drawobject->vertices ):0; while(node) { float *co= ss->mvert[node->Index].co; const float val[3]= {co[0]+(ss->cache->location[0]-co[0])*node->Fade, co[1]+(ss->cache->location[1]-co[1])*node->Fade, co[2]+(ss->cache->location[2]-co[2])*node->Fade}; + + if( buffer != 0 ) { + IndexLink *cur = &ss->drawobject->indices[node->Index]; + while( cur != 0 && cur->element != -1 ) { + sculpt_clip(s, ss, &buffer[cur->element*3], val); + cur = cur->next; + } + } + sculpt_clip(s, ss, co, val); node= node->next; } + if( buffer != 0 ) + GPU_buffer_unlock( ss->drawobject->vertices ); } static void do_grab_brush(Sculpt *sd, SculptSession *ss) @@ -405,6 +442,7 @@ static void do_grab_brush(Sculpt *sd, SculptSession *ss) ActiveData *node= ss->cache->grab_active_verts[ss->cache->symmetry].first; float add[3]; float grab_delta[3]; + float *buffer = ss->drawobject!=0?(float *)GPU_buffer_lock( ss->drawobject->vertices ):0; VecCopyf(grab_delta, ss->cache->grab_delta_symmetry); @@ -414,10 +452,21 @@ static void do_grab_brush(Sculpt *sd, SculptSession *ss) VecCopyf(add, grab_delta); VecMulf(add, node->Fade); VecAddf(add, add, co); + + if( buffer != 0 ) { + IndexLink *cur = &ss->drawobject->indices[node->Index]; + while( cur != 0 && cur->element != -1 ) { + sculpt_clip(sd, ss, &buffer[cur->element*3], add); + cur = cur->next; + } + } + sculpt_clip(sd, ss, co, add); node= node->next; } + if( buffer != 0 ) + GPU_buffer_unlock( ss->drawobject->vertices ); } @@ -425,6 +474,7 @@ static void do_layer_brush(Sculpt *sd, SculptSession *ss, const ListBase *active { float area_normal[3]; ActiveData *node= active_verts->first; + float *buffer; float lim= ss->cache->radius / 4; if(ss->cache->flip) @@ -432,6 +482,7 @@ static void do_layer_brush(Sculpt *sd, SculptSession *ss, const ListBase *active calc_area_normal(sd, ss, area_normal, active_verts); + buffer = ss->drawobject!=0?(float *)GPU_buffer_lock( ss->drawobject->vertices ):0; while(node){ float *disp= &ss->layer_disps[node->Index]; float *co= ss->mvert[node->Index].co; @@ -447,17 +498,28 @@ static void do_layer_brush(Sculpt *sd, SculptSession *ss, const ListBase *active val[1] = ss->mesh_co_orig[node->Index][1]+area_normal[1] * *disp*ss->cache->scale[1]; val[2] = ss->mesh_co_orig[node->Index][2]+area_normal[2] * *disp*ss->cache->scale[2]; + if( buffer != 0 ) { + IndexLink *cur = &ss->drawobject->indices[node->Index]; + while( cur != 0 && cur->element != -1 ) { + sculpt_clip(sd, ss, &buffer[cur->element*3], val); + cur = cur->next; + } + } + sculpt_clip(sd, ss, co, val); node= node->next; } + if( buffer != 0 ) + GPU_buffer_unlock( ss->drawobject->vertices ); } static void do_inflate_brush(Sculpt *s, SculptSession *ss, const ListBase *active_verts) { ActiveData *node= active_verts->first; float add[3]; - + float *buffer = ss->drawobject!=0?(float *)GPU_buffer_lock( ss->drawobject->vertices ):0; + while(node) { float *co= ss->mvert[node->Index].co; short *no= ss->mvert[node->Index].no; @@ -471,10 +533,20 @@ static void do_inflate_brush(Sculpt *s, SculptSession *ss, const ListBase *activ add[2]*= ss->cache->scale[2]; VecAddf(add, add, co); + if( buffer != 0 ) { + IndexLink *cur = &ss->drawobject->indices[node->Index]; + while( cur != 0 && cur->element != -1 ) { + sculpt_clip(s, ss, &buffer[cur->element*3], add); + cur = cur->next; + } + } + sculpt_clip(s, ss, co, add); node= node->next; } + if( buffer != 0 ) + GPU_buffer_unlock( ss->drawobject->vertices ); } static void calc_flatten_center(SculptSession *ss, ActiveData *node, float co[3]) @@ -535,7 +607,7 @@ static void do_flatten_clay_brush(Sculpt *sd, SculptSession *ss, const ListBase float area_normal[3]; float cntr[3], cntr2[3], bstr = 0; int flip = 0; - + float *buffer; calc_area_normal(sd, ss, area_normal, active_verts); calc_flatten_center(ss, node, cntr); @@ -547,7 +619,9 @@ static void do_flatten_clay_brush(Sculpt *sd, SculptSession *ss, const ListBase cntr2[2]=cntr[2]+area_normal[2]*bstr*ss->cache->scale[2]; flip = bstr < 0; } - + + buffer = ss->drawobject!=0?(float *)GPU_buffer_lock( ss->drawobject->vertices ):0; + while(node){ float *co= ss->mvert[node->Index].co; float intr[3], val[3]; @@ -573,11 +647,21 @@ static void do_flatten_clay_brush(Sculpt *sd, SculptSession *ss, const ListBase VecAddf(val, val, co); + if( buffer != 0 ) { + IndexLink *cur = &ss->drawobject->indices[node->Index]; + while( cur != 0 && cur->element != -1 ) { + sculpt_clip(sd, ss, &buffer[cur->element*3], val); + cur = cur->next; + } + } sculpt_clip(sd, ss, co, val); + } node= node->next; } + if( buffer != 0 ) + GPU_buffer_unlock( ss->drawobject->vertices ); } /* Uses symm to selectively flip any axis of a coordinate. */ @@ -898,7 +982,8 @@ static void add_face_normal(vec3f *norm, MVert *mvert, const MFace* face, float static void update_damaged_vert(SculptSession *ss, ListBase *lb) { ActiveData *vert; - + + float *buffer = ss->drawobject!=0?(float *)GPU_buffer_lock( ss->drawobject->normals ):0; for(vert= lb->first; vert; vert= vert->next) { vec3f norm= {0,0,0}; IndexNode *face= ss->fmap[vert->Index].first; @@ -915,7 +1000,32 @@ static void update_damaged_vert(SculptSession *ss, ListBase *lb) ss->mvert[vert->Index].no[0]=norm.x*32767; ss->mvert[vert->Index].no[1]=norm.y*32767; ss->mvert[vert->Index].no[2]=norm.z*32767; + + if( buffer != 0 ) { + IndexLink *cur = &ss->drawobject->indices[vert->Index]; + while( cur != 0 && cur->element != -1 ) { + int i = ss->drawobject->faceRemap[cur->element/3]; + if( ss->mface[i].flag & ME_SMOOTH ) { + VECCOPY(&buffer[cur->element*3],ss->mvert[vert->Index].no); + } + else { + float norm[3]; + if( ss->mface[i].v4 ) + CalcNormFloat4(ss->mvert[ss->mface[i].v1].co, ss->mvert[ss->mface[i].v2].co, ss->mvert[ss->mface[i].v3].co, ss->mvert[ss->mface[i].v4].co, norm); + else + CalcNormFloat(ss->mvert[ss->mface[i].v1].co, ss->mvert[ss->mface[i].v2].co, ss->mvert[ss->mface[i].v3].co, norm); + VECCOPY(&buffer[(cur->element-cur->element%3)*3],norm); + VECCOPY(&buffer[(cur->element-cur->element%3+1)*3],norm); + VECCOPY(&buffer[(cur->element-cur->element%3+2)*3],norm); + } + + //VECCOPY(&buffer[cur->element*3],ss->mvert[vert->Index].no); + cur = cur->next; + } + } } + if( buffer != 0 ) + GPU_buffer_unlock( ss->drawobject->normals ); } static void calc_damaged_verts(SculptSession *ss) @@ -1004,9 +1114,10 @@ static void sculpt_update_mesh_elements(bContext *C) Object *ob = CTX_data_active_object(C); SculptSession *ss = ob->sculpt; int oldtotvert = ss->totvert; + DerivedMesh *dm = mesh_get_derived_final(CTX_data_scene(C), ob, CD_MASK_BAREMESH); if((ss->multires = sculpt_multires_active(ob))) { - DerivedMesh *dm = mesh_get_derived_final(CTX_data_scene(C), ob, CD_MASK_BAREMESH); + //DerivedMesh *dm = mesh_get_derived_final(CTX_data_scene(C), ob, CD_MASK_BAREMESH); ss->totvert = dm->getNumVerts(dm); ss->totface = dm->getNumFaces(dm); ss->mvert = dm->getVertDataArray(dm, CD_MVERT); @@ -1021,6 +1132,12 @@ static void sculpt_update_mesh_elements(bContext *C) ss->mface = me->mface; ss->face_normals = NULL; } + if( GPU_buffer_legacy( dm ) ) { + ss->drawobject = 0; + } + else { + ss->drawobject = dm->drawObject; + } if(ss->totvert != oldtotvert) { if(ss->projverts) MEM_freeN(ss->projverts); @@ -1332,16 +1449,27 @@ static void sculpt_restore_mesh(Sculpt *sd, SculptSession *ss) { StrokeCache *cache = ss->cache; Brush *brush = paint_brush(&sd->paint); + float *buffer; int i; - + /* Restore the mesh before continuing with anchored stroke */ if((brush->flag & BRUSH_ANCHORED) && ss->mesh_co_orig) { + buffer = buffer = ss->drawobject!=0?(float *)GPU_buffer_lock( ss->drawobject->normals ):0; for(i = 0; i < ss->totvert; ++i) { VecCopyf(ss->mvert[i].co, ss->mesh_co_orig[i]); ss->mvert[i].no[0] = cache->orig_norms[i][0]; ss->mvert[i].no[1] = cache->orig_norms[i][1]; ss->mvert[i].no[2] = cache->orig_norms[i][2]; + if( buffer != 0 ) { + IndexLink *cur = &ss->drawobject->indices[i]; + while( cur != 0 && cur->element != -1 ) { + VECCOPY(&buffer[cur->element*3],cache->orig_norms[i]); + cur = cur->next; + } + } } + if( buffer != 0 ) + GPU_buffer_unlock( ss->drawobject->normals ); if(ss->face_normals) { float *fn = ss->face_normals; |