Sculpt: svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r24095...
[blender.git] / source / blender / editors / space_view3d / drawobject.c
index 9e773298d4aea7f04ebf4db54e7d3096626509c9..f7dba10200a0dbfe5bd463c13acbf06752179b0b 100644 (file)
 #include "ED_mesh.h"
 #include "ED_particle.h"
 #include "ED_screen.h"
+#include "ED_sculpt.h"
 #include "ED_types.h"
 #include "ED_util.h"
 
@@ -212,7 +213,7 @@ static void view3d_project_short_noclip(ARegion *ar, float *vec, short *adr)
 
 int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt)
 {
-       if(!GPU_extensions_minimum_support())
+       if(!GPU_glsl_support())
                return 0;
        if(G.f & G_PICKSEL)
                return 0;
@@ -922,11 +923,11 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
                /* draw the circle/square representing spotbl */
                if(la->type==LA_SPOT) {
                        float spotblcirc = fabs(z)*(1 - pow(la->spotblend, 2));
-                       /* make sure the line is always visible - prevent it from reaching the outer border (or 0) 
-                        * values are kinda arbitrary - just what seemed to work well */
-                       if (spotblcirc == 0) spotblcirc = 0.15;
-                       else if (spotblcirc == fabs(z)) spotblcirc = fabs(z) - 0.07;
-                       circ(0.0, 0.0, spotblcirc);
+                       /* hide line if it is zero size or overlaps with outer border,
+                          previously it adjusted to always to show it but that seems
+                          confusing because it doesn't show the actual blend size */
+                       if (spotblcirc != 0 && spotblcirc != fabs(z))
+                               circ(0.0, 0.0, spotblcirc);
                }
                
        }
@@ -2691,7 +2692,7 @@ static void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm)
                   drawFacesSolid() doesn't draw the transparent faces */
                if(ob->dtx & OB_DRAWTRANSP) {
                        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 
-                       dm->drawFacesSolid(dm, GPU_enable_material);
+                       dm->drawFacesSolid(dm, NULL, GPU_enable_material);
                        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
                        GPU_disable_material();
                }
@@ -2710,7 +2711,7 @@ static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmoot
        return 1;
 }
 
-static void draw_mesh_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt, int flag)
+static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base, int dt, int flag)
 {
        Object *ob= base->object;
        Mesh *me = ob->data;
@@ -2783,7 +2784,7 @@ static void draw_mesh_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
                }
        }
        else if(dt==OB_SOLID) {
-               if((v3d->flag&V3D_SELECT_OUTLINE) && (base->flag&SELECT) && !draw_wire)
+               if((v3d->flag&V3D_SELECT_OUTLINE) && (base->flag&SELECT) && !draw_wire && !ob->sculpt)
                        draw_mesh_object_outline(v3d, ob, dm);
 
                glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, me->flag & ME_TWOSIDED );
@@ -2791,7 +2792,21 @@ static void draw_mesh_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
                glEnable(GL_LIGHTING);
                glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
 
-               dm->drawFacesSolid(dm, GPU_enable_material);
+               if(ob->sculpt) {
+                       float planes[4][4];
+                       float (*fpl)[4] = NULL;
+
+                       if(ob->sculpt->partial_redraw) {
+                               sculpt_get_redraw_planes(planes, ar, rv3d, ob);
+                               fpl = planes;
+                               ob->sculpt->partial_redraw = 0;
+                       }
+
+                       dm->drawFacesSolid(dm, fpl, GPU_enable_material);
+               }
+               else
+                       dm->drawFacesSolid(dm, NULL, GPU_enable_material);
+
                GPU_disable_material();
 
                glFrontFace(GL_CCW);
@@ -2802,7 +2817,8 @@ static void draw_mesh_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
                } else {
                        UI_ThemeColor(TH_WIRE);
                }
-               dm->drawLooseEdges(dm);
+               if(!ob->sculpt)
+                       dm->drawLooseEdges(dm);
        }
        else if(dt==OB_SHADED) {
                int do_draw= 1; /* to resolve all G.f settings below... */
@@ -2920,7 +2936,7 @@ static void draw_mesh_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
 }
 
 /* returns 1 if nothing was drawn, for detecting to draw an object center */
-static int draw_mesh_object(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt, int flag)
+static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base, int dt, int flag)
 {
        Object *ob= base->object;
        Object *obedit= scene->obedit;
@@ -2970,7 +2986,7 @@ static int draw_mesh_object(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
                                        (check_alpha)? &do_alpha_pass: NULL);
                        }
 
-                       draw_mesh_fancy(scene, v3d, rv3d, base, dt, flag);
+                       draw_mesh_fancy(scene, ar, v3d, rv3d, base, dt, flag);
 
                        GPU_end_object_materials();
                        
@@ -3658,7 +3674,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
        //if(part->flag&PART_GLOB_TIME)
        cfra=bsystem_time(scene, 0, (float)CFRA, 0.0f);
 
-       if(draw_as==PART_DRAW_PATH && psys->pathcache==NULL)
+       if(draw_as==PART_DRAW_PATH && psys->pathcache==NULL && psys->childcache==NULL)
                draw_as=PART_DRAW_DOT;
 
 /* 3. */
@@ -4009,6 +4025,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
 
                if(totchild && (part->draw&PART_DRAW_PARENT)==0)
                        totpart=0;
+               else if(psys->pathcache==NULL)
+                       totpart=0;
 
                /* draw actual/parent particles */
                cache=psys->pathcache;
@@ -4155,7 +4173,7 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Obj
        PTCacheEditKey *key;
        ParticleEditSettings *pset = PE_settings(scene);
        int i, k, totpoint = edit->totpoint, timed = pset->flag & PE_FADE_TIME ? pset->fade_frames : 0;
-       int steps;
+       int steps=1;
        char nosel[4], sel[4];
        float sel_col[3];
        float nosel_col[3];
@@ -4237,7 +4255,7 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Obj
                                if(!(point->flag & PEP_HIDE))
                                        totkeys += point->totkey;
 
-                       if(!(edit->points->keys->flag & PEK_USE_WCO))
+                       if(edit->points && !(edit->points->keys->flag & PEK_USE_WCO))
                                pd=pdata=MEM_callocN(totkeys*3*sizeof(float), "particle edit point data");
                        cd=cdata=MEM_callocN(totkeys*(timed?4:3)*sizeof(float), "particle edit color data");
 
@@ -5564,7 +5582,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
 
        switch( ob->type) {
                case OB_MESH:
-                       empty_object= draw_mesh_object(scene, v3d, rv3d, base, dt, flag);
+                       empty_object= draw_mesh_object(scene, ar, v3d, rv3d, base, dt, flag);
                        if(flag!=DRAW_CONSTCOLOR) dtx &= ~OB_DRAWWIRE; // mesh draws wire itself
 
                        break;
@@ -5709,6 +5727,22 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
        }
        if(ob->pd && ob->pd->forcefield) draw_forcefield(scene, ob);
 
+       /* particle mode has to be drawn first so that possible child particles get cached in edit mode */
+       if(             (warning_recursive==0) &&
+                       (flag & DRAW_PICKING)==0 &&
+                       (!scene->obedit)        
+         ) {
+
+               if(ob->mode & OB_MODE_PARTICLE_EDIT && ob==OBACT) {
+                       PTCacheEdit *edit = PE_get_current(scene, ob);
+                       if(edit) {
+                               wmLoadMatrix(rv3d->viewmat);
+                               draw_ptcache_edit(scene, v3d, rv3d, ob, edit, dt);
+                               wmMultMatrix(ob->obmat);
+                       }
+               }
+       }
+
        /* code for new particle system */
        if(             (warning_recursive==0) &&
                        (ob->particlesystem.first) &&
@@ -5733,21 +5767,6 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                //glDepthMask(GL_TRUE);
                if(col) cpack(col);
        }
-       
-       if(             (warning_recursive==0) &&
-                       (flag & DRAW_PICKING)==0 &&
-                       (!scene->obedit)        
-         ) {
-
-               if(ob->mode & OB_MODE_PARTICLE_EDIT && ob==OBACT) {
-                       PTCacheEdit *edit = PE_get_current(scene, ob);
-                       if(edit) {
-                               wmLoadMatrix(rv3d->viewmat);
-                               draw_ptcache_edit(scene, v3d, rv3d, ob, edit, dt);
-                               wmMultMatrix(ob->obmat);
-                       }
-               }
-       }
 
        /* draw code for smoke */
        if((md = modifiers_findByType(ob, eModifierType_Smoke)))
@@ -6083,7 +6102,7 @@ static void bbs_mesh_solid_EM(Scene *scene, View3D *v3d, Object *ob, DerivedMesh
        }
 }
 
-static int bbs_mesh_solid__setDrawOpts(void *userData, int index, int *drawSmooth_r)
+static int bbs_mesh_solid_hide__setDrawOpts(void *userData, int index, int *drawSmooth_r)
 {
        Mesh *me = userData;
 
@@ -6093,7 +6112,14 @@ static int bbs_mesh_solid__setDrawOpts(void *userData, int index, int *drawSmoot
                return 0;
        }
 }
+
 static int bbs_mesh_solid__setDrawOpts_legacy(void *userData, int index, int *drawSmooth_r)
+{
+       WM_set_framebuffer_index_color(index+1);
+       return 1;
+}
+
+static int bbs_mesh_solid_hide__setDrawOpts_legacy(void *userData, int index, int *drawSmooth_r)
 {
        Mesh *me = userData;
 
@@ -6105,13 +6131,13 @@ static int bbs_mesh_solid__setDrawOpts_legacy(void *userData, int index, int *dr
        }
 }
 
-/* TODO remove this - since face select mode now only works with painting */
 static void bbs_mesh_solid(Scene *scene, View3D *v3d, Object *ob)
 {
        DerivedMesh *dm = mesh_get_derived_final(scene, ob, v3d->customdata_mask);
        Mesh *me = (Mesh*)ob->data;
        MCol *colors;
        int i,j;
+       int face_sel_mode = (me->flag & ME_EDIT_PAINT_MASK) ? 1:0;
        
        glColor3ub(0, 0, 0);
                
@@ -6124,7 +6150,7 @@ static void bbs_mesh_solid(Scene *scene, View3D *v3d, Object *ob)
                                ind = index[i];
                        else
                                ind = i;
-                       if (!(me->mface[ind].flag&ME_HIDE)) {
+                       if (face_sel_mode==0 || !(me->mface[ind].flag&ME_HIDE)) {
                                unsigned int fbindex = index_to_framebuffer(ind+1);
                                for(j=0;j<4;j++) {
                                        colors[i*4+j].b = ((fbindex)&0xFF);
@@ -6140,10 +6166,13 @@ static void bbs_mesh_solid(Scene *scene, View3D *v3d, Object *ob)
                CustomData_add_layer( &dm->faceData, CD_ID_MCOL, CD_ASSIGN, colors, dm->numFaceData );
                GPU_buffer_free(dm->drawObject->colors,0);
                dm->drawObject->colors = 0;
-               dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, me, 1);
+
+               if(face_sel_mode)       dm->drawMappedFaces(dm, bbs_mesh_solid_hide__setDrawOpts, me, 1);
+               else                            dm->drawMappedFaces(dm, NULL, me, 1);
        }
        else {
-               dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts_legacy, me, 0);
+               if(face_sel_mode)       dm->drawMappedFaces(dm, bbs_mesh_solid_hide__setDrawOpts_legacy, me, 0);
+               else                            dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts_legacy, me, 0);
        }
 
        dm->release(dm);
@@ -6161,7 +6190,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
        switch( ob->type) {
        case OB_MESH:
        {
-               if((ob->mode & OB_MODE_EDIT)==0) {
+               if(ob->mode & OB_MODE_EDIT) {
                        Mesh *me= ob->data;
                        EditMesh *em= me->edit_mesh;
 
@@ -6247,7 +6276,7 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r
                glEnable(GL_LIGHTING);
                
                if(dm) {
-                       dm->drawFacesSolid(dm, GPU_enable_material);
+                       dm->drawFacesSolid(dm, NULL, GPU_enable_material);
                        GPU_end_object_materials();
                }
                else if(edm)