diff options
Diffstat (limited to 'source/blender/editors/space_view3d/drawobject.c')
-rw-r--r-- | source/blender/editors/space_view3d/drawobject.c | 662 |
1 files changed, 616 insertions, 46 deletions
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 56de06bedac..848362f91d7 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -29,6 +29,7 @@ #include "MEM_guardedalloc.h" +#include "DNA_armature_types.h" #include "DNA_camera_types.h" #include "DNA_curve_types.h" #include "DNA_constraint_types.h" /* for drawing constraint */ @@ -48,6 +49,7 @@ #include "BLI_string.h" #include "BLI_math.h" #include "BLI_memarena.h" +#include "BLI_rand.h" #include "BKE_anim.h" /* for the where_on_path function */ #include "BKE_armature.h" @@ -58,6 +60,7 @@ #include "BKE_DerivedMesh.h" #include "BKE_deform.h" #include "BKE_displist.h" +#include "BKE_editstrands.h" #include "BKE_font.h" #include "BKE_global.h" #include "BKE_image.h" @@ -88,6 +91,7 @@ #include "GPU_draw.h" #include "GPU_extensions.h" #include "GPU_select.h" +#include "GPU_buffers.h" #include "ED_mesh.h" #include "ED_particle.h" @@ -101,6 +105,10 @@ #include "WM_api.h" #include "BLF_api.h" +#ifdef WITH_OPENVDB +# include "openvdb_capi.h" +#endif + #include "view3d_intern.h" /* bad level include */ /* Workaround for sequencer scene render mode. @@ -311,9 +319,6 @@ bool draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, const char dt) static bool check_alpha_pass(Base *base) { - if (base->flag & OB_FROMDUPLI) - return false; - if (G.f & G_PICKSEL) return false; @@ -3973,7 +3978,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d, static void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm) { if ((v3d->transp == false) && /* not when we draw the transparent pass */ - (ob->mode & OB_MODE_ALL_PAINT) == false) /* not when painting (its distracting) - campbell */ + (ob->mode & OB_MODE_ALL_BRUSH) == false) /* not when painting (its distracting) - campbell */ { glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); glDepthMask(0); @@ -4346,21 +4351,29 @@ static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3 } draw_mesh_fancy(scene, ar, v3d, rv3d, base, dt, ob_wire_col, dflag); - + GPU_end_object_materials(); if (me->totvert == 0) retval = true; } } - if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0 && (v3d->flag2 & V3D_RENDER_SHADOW) == 0) { + if ((dflag & DRAW_PICKING) == 0 && ((base->flag & OB_FROMDUPLI) == 0 || (ob->dtx & OB_DRAWTRANSP)) && (v3d->flag2 & V3D_RENDER_SHADOW) == 0) { /* GPU_begin_object_materials checked if this is needed */ if (do_alpha_after) { - if (ob->dtx & OB_DRAWXRAY) { + /* duplis only for transparency */ + if ((ob->dtx & OB_DRAWXRAY) && !(base->flag & OB_FROMDUPLI)) { ED_view3d_after_add(&v3d->afterdraw_xraytransp, base, dflag); } else { - ED_view3d_after_add(&v3d->afterdraw_transp, base, dflag); + if (base->flag & OB_FROMDUPLI) { + Base *nbase = MEM_mallocN(sizeof(Base), "dupli_trans"); + *nbase = *base; + ED_view3d_after_add(&v3d->afterdraw_transp, nbase, dflag); + } + else { + ED_view3d_after_add(&v3d->afterdraw_transp, base, dflag); + } } } else if (ob->dtx & OB_DRAWXRAY && ob->dtx & OB_DRAWTRANSP) { @@ -4823,6 +4836,377 @@ static bool drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *ba } /* *********** drawing for particles ************* */ + +BLI_INLINE unsigned int hash_int_2d(unsigned int kx, unsigned int ky) +{ +#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) + + unsigned int a, b, c; + + a = b = c = 0xdeadbeef + (2 << 2) + 13; + a += kx; + b += ky; + + c ^= b; c -= rot(b,14); + a ^= c; a -= rot(c,11); + b ^= a; b -= rot(a,25); + c ^= b; c -= rot(b,16); + a ^= c; a -= rot(c,4); + b ^= a; b -= rot(a,14); + c ^= b; c -= rot(b,24); + + return c; + +#undef rot +} + +BLI_INLINE unsigned int hash_int(unsigned int k) +{ + return hash_int_2d(k, 0); +} + +static void particle_path_color(int index, float col[3]) +{ + unsigned seed = hash_int(index); + + BLI_srandom(seed); + hsv_to_rgb(BLI_frand(), 1.0f, 1.0f, col+0, col+1, col+2); +} + +#ifdef USE_PARTICLE_HULL_DRAWING +static void draw_particle_hull_section(ParticleCacheKey *path, ParticleCacheKey *npath) +{ + int segments = max_ii(path->segments, npath->segments); + int k; + + for (k = 0; k < segments; ++k) { + int k0 = max_ii(k-1, 0); + int k1 = k; + int k2 = k+1; + int k3 = min_ii(k+2, path->segments); + int nk0 = max_ii(min_ii(k-1, npath->segments), 0); + int nk1 = min_ii(k, npath->segments); + int nk2 = min_ii(k+1, npath->segments); + int nk3 = min_ii(k+2, npath->segments); + float *co[2][4]; + + float nor01[3], nor11[3], nor02[3], nor12[3]; + + co[0][0] = path[k0].co; + co[0][1] = path[k1].co; + co[0][2] = path[k2].co; + co[0][3] = path[k3].co; + co[1][0] = npath[nk0].co; + co[1][1] = npath[nk1].co; + co[1][2] = npath[nk2].co; + co[1][3] = npath[nk3].co; + + normal_quad_v3(nor01, co[0][1], co[0][0], co[1][1], co[0][2]); + normal_quad_v3(nor02, co[0][2], co[0][1], co[1][2], co[0][3]); + normal_quad_v3(nor11, co[1][1], co[1][2], co[0][1], co[1][0]); + normal_quad_v3(nor12, co[1][2], co[1][3], co[0][2], co[1][1]); + + glNormal3fv(nor01); + glVertex3fv(path[k1].co); + glNormal3fv(nor11); + glVertex3fv(npath[nk1].co); + glNormal3fv(nor12); + glVertex3fv(npath[nk2].co); + glNormal3fv(nor02); + glVertex3fv(path[k2].co); + } +} + +static void draw_particle_hull_cap(ParticleCacheKey *a0, ParticleCacheKey *a1, ParticleCacheKey *a2, ParticleCacheKey *a3, + ParticleCacheKey *b0, ParticleCacheKey *b1, ParticleCacheKey *b2, ParticleCacheKey *b3) +{ + float *ca[4], *cb[4]; + + float na[4][3], nb[4][3]; + + if (a1 == b1) { + ca[1] = cb[1] = a1[a1->segments].co; + ca[2] = a2[a2->segments].co; + cb[2] = b2[b2->segments].co; + ca[3] = a3[a3->segments].co; + cb[3] = b3[b3->segments].co; + + normal_tri_v3(na[1], ca[1], cb[2], ca[2]); + normal_quad_v3(na[2], ca[2], ca[1], cb[2], ca[3]); + normal_quad_v3(nb[2], cb[2], cb[3], ca[2], cb[1]); + + glNormal3fv(na[2]); + glVertex3fv(ca[2]); + + glNormal3fv(na[1]); + glVertex3fv(ca[1]); + + glNormal3fv(nb[2]); + glVertex3fv(cb[2]); + } + else if (a2 == b2) { + ca[0] = a0[a0->segments].co; + cb[0] = b0[b0->segments].co; + ca[1] = a1[a1->segments].co; + cb[1] = b1[b1->segments].co; + ca[2] = cb[2] = a2[a2->segments].co; + + normal_quad_v3(na[1], ca[1], ca[0], cb[1], ca[2]); + normal_quad_v3(nb[1], cb[1], cb[2], ca[1], cb[0]); + normal_tri_v3(na[2], ca[2], ca[1], cb[1]); + + glNormal3fv(na[1]); + glVertex3fv(ca[1]); + + glNormal3fv(nb[1]); + glVertex3fv(cb[1]); + + glNormal3fv(nb[2]); + glVertex3fv(cb[2]); + } + else { + ca[0] = a0[a0->segments].co; + cb[0] = b0[b0->segments].co; + ca[1] = a1[a1->segments].co; + cb[1] = b1[b1->segments].co; + ca[2] = a2[a2->segments].co; + cb[2] = b2[b2->segments].co; + ca[3] = a3[a3->segments].co; + cb[3] = b3[b3->segments].co; + + normal_quad_v3(na[1], ca[1], ca[0], cb[1], ca[2]); + normal_quad_v3(na[2], ca[2], ca[1], cb[2], ca[3]); + normal_quad_v3(nb[1], cb[1], cb[2], ca[1], cb[0]); + normal_quad_v3(nb[2], cb[2], cb[3], ca[2], cb[1]); + + glNormal3fv(na[1]); + glVertex3fv(ca[1]); + + glNormal3fv(nb[1]); + glVertex3fv(cb[1]); + + glNormal3fv(nb[2]); + glVertex3fv(cb[2]); + + glNormal3fv(na[2]); + glVertex3fv(ca[2]); + + glNormal3fv(na[1]); + glVertex3fv(ca[1]); + + glNormal3fv(nb[2]); + glVertex3fv(cb[2]); + } +} + +BLI_INLINE bool particle_path_valid(ParticleCacheKey **cache, int p) +{ + return (cache[p]->segments >= 0 && cache[p]->hull_parent >= 0); +} + +BLI_INLINE int particle_path_next(ParticleCacheKey **cache, int pmax, int p) +{ + do { + ++p; + if (p >= pmax) + break; + if (particle_path_valid(cache, p)) + break; + } while (true); + + return p; +} + +BLI_INLINE int particle_path_prev(ParticleCacheKey **cache, int pmin, int p) +{ + do { + --p; + if (p < pmin) + break; + if (particle_path_valid(cache, p)) + break; + } while (true); + + return p; +} + +static void draw_particle_hair_hull(Scene *UNUSED(scene), View3D *v3d, RegionView3D *rv3d, + Base *base, ParticleSystem *psys, + const char UNUSED(ob_dt), const short dflag) +{ + Object *ob = base->object; + ParticleSettings *part = psys->part; + Material *ma = give_current_material(ob, part->omat); + unsigned char tcol[4] = {0, 0, 0, 255}; + GLint polygonmode[2]; + int totchild; + + bool draw_constcolor = dflag & DRAW_CONSTCOLOR; + + ParticleCacheKey **cache; + + if (part->type == PART_HAIR && !psys->childcache) + totchild = 0; + else + totchild = psys->totchild * part->disp / 100; + + if (v3d->zbuf) + glDepthMask(true); + + glGetIntegerv(GL_POLYGON_MODE, polygonmode); + + cache = psys->childcache; + + switch (part->draw_col) { + case PART_DRAW_COL_NONE: + draw_constcolor = true; + break; + case PART_DRAW_COL_MAT: + if (ma) + rgb_float_to_uchar(tcol, &(ma->r)); + else + tcol[0] = tcol[1] = tcol[2] = 1.0f; + break; + case PART_DRAW_COL_VEL: + tcol[0] = tcol[1] = tcol[2] = 1.0f; + break; + case PART_DRAW_COL_ACC: + tcol[0] = tcol[1] = tcol[2] = 1.0f; + break; + case PART_DRAW_COL_PARENT: + /* handled per child group */ + break; + default: + BLI_assert(0); /* should never happen */ + break; + } + + if (!draw_constcolor) { + glColor3ubv(tcol); + } + + /* draw child particles */ + { + int pstart; + float col[3]; + + glEnable(GL_LIGHTING); + glEnable(GL_COLOR_MATERIAL); + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + glShadeModel(GL_SMOOTH); + + glBegin(GL_QUADS); + pstart = particle_path_next(cache, totchild, -1); + while (pstart < totchild) { + int p = pstart; + int np = particle_path_next(cache, totchild, p); + + if (part->draw_col == PART_DRAW_COL_PARENT) { + particle_path_color(pstart, col); + rgb_float_to_uchar(tcol, col); + glColor3ubv(tcol); + } + + while (np < totchild && cache[np]->hull_parent == cache[pstart]->hull_parent) { + draw_particle_hull_section(cache[p], cache[np]); + + p = np; + np = particle_path_next(cache, totchild, np); + } + if (p > pstart + 1) + draw_particle_hull_section(cache[p], cache[pstart]); + + pstart = np; + } + glEnd(); + + glBegin(GL_TRIANGLES); + pstart = particle_path_next(cache, totchild, -1); + while (pstart < totchild) { + int groupend; + + if (part->draw_col == PART_DRAW_COL_PARENT) { + particle_path_color(pstart, col); + rgb_float_to_uchar(tcol, col); + glColor3ubv(tcol); + } + + { + int p = particle_path_next(cache, totchild, pstart); + while (p < totchild && cache[p]->hull_parent == cache[pstart]->hull_parent) { + p = particle_path_next(cache, totchild, p); + } + groupend = p; + } + + { + int a[4], b[4]; + + #define NEXT \ + a[3] = a[2]; \ + b[3] = b[2]; \ + a[2] = a[1]; \ + b[2] = b[1]; \ + a[1] = a[0]; \ + b[1] = b[0]; \ + a[0] = particle_path_next(cache, groupend, a[0]); \ + b[0] = particle_path_prev(cache, pstart, b[0]); + + a[3] = pstart - 1; + b[3] = particle_path_prev(cache, pstart, groupend) + 1; + a[2] = particle_path_next(cache, groupend, a[3]); + b[2] = particle_path_prev(cache, pstart, b[3]); + a[1] = particle_path_next(cache, groupend, a[2]); + b[1] = particle_path_prev(cache, pstart, b[2]); + a[0] = particle_path_next(cache, groupend, a[1]); + b[0] = particle_path_prev(cache, pstart, b[1]); + + /* first element */ + if (a[1] <= b[1]) { + if (a[0] <= b[0]) + draw_particle_hull_cap(cache[a[0]], cache[a[1]], cache[a[2]], cache[a[2]], + cache[b[0]], cache[b[1]], cache[b[2]], cache[b[2]]); + else + draw_particle_hull_cap(cache[a[1]], cache[a[1]], cache[a[2]], cache[a[2]], + cache[b[1]], cache[b[1]], cache[b[2]], cache[b[2]]); + } + NEXT + + while (true) { + if (a[1] <= b[1]) { + if (a[0] <= b[0]) + draw_particle_hull_cap(cache[a[0]], cache[a[1]], cache[a[2]], cache[a[3]], + cache[b[0]], cache[b[1]], cache[b[2]], cache[b[3]]); + else + draw_particle_hull_cap(cache[a[1]], cache[a[1]], cache[a[2]], cache[a[3]], + cache[b[1]], cache[b[1]], cache[b[2]], cache[b[3]]); + } + else + break; + + NEXT + } + + #undef NEXT + } + + pstart = groupend; + } + glEnd(); + + glDisable(GL_COLOR_MATERIAL); + glDisable(GL_LIGHTING); + } + + glPolygonMode(GL_FRONT, polygonmode[0]); + glPolygonMode(GL_BACK, polygonmode[1]); + + if ((base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP)) { + glLoadMatrixf(rv3d->viewmat); + } +} +#endif + static void draw_particle_arrays(int draw_as, int totpoint, int ob_dt, int select) { /* draw created data arrays */ @@ -4847,6 +5231,7 @@ static void draw_particle_arrays(int draw_as, int totpoint, int ob_dt, int selec break; } } + static void draw_particle(ParticleKey *state, int draw_as, short draw, float pixsize, float imat[4][4], const float draw_line[2], ParticleBillboardData *bb, ParticleDrawData *pdd) { @@ -4997,6 +5382,7 @@ static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix } } } + static void draw_particle_data(ParticleSystem *psys, RegionView3D *rv3d, ParticleKey *state, int draw_as, float imat[4][4], ParticleBillboardData *bb, ParticleDrawData *pdd, @@ -5060,7 +5446,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv Material *ma; float vel[3], imat[4][4]; float timestep, pixsize_scale = 1.0f, pa_size, r_tilt, r_length; - float pa_time, pa_birthtime, pa_dietime, pa_health, intensity; + float pa_time, pa_birthtime, pa_dietime, pa_health; float cfra; float ma_col[3] = {0.0f, 0.0f, 0.0f}; int a, totpart, totpoint = 0, totve = 0, drawn, draw_as, totchild = 0; @@ -5079,14 +5465,17 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv /* don't draw normal paths in edit mode */ if (psys_in_edit_mode(scene, psys) && (pset->flag & PE_DRAW_PART) == 0) return; - - if (part->draw_as == PART_DRAW_REND) - draw_as = part->ren_as; - else - draw_as = part->draw_as; - - if (draw_as == PART_DRAW_NOT) + + draw_as = part->draw_as == PART_DRAW_REND ? part->ren_as : part->draw_as; + if (draw_as == PART_DRAW_NOT) { + return; + } + else if (draw_as == PART_DRAW_HULL) { +#ifdef USE_PARTICLE_HULL_DRAWING + draw_particle_hair_hull(scene, v3d, rv3d, base, psys, ob_dt, dflag); +#endif return; + } /* prepare curvemapping tables */ if ((psys->part->child_flag & PART_CHILD_USE_CLUMP_CURVE) && psys->part->clumpcurve) @@ -5330,20 +5719,32 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv r_length = psys_frand(psys, a + 22); if (part->draw_col > PART_DRAW_COL_MAT) { + float intensity; switch (part->draw_col) { case PART_DRAW_COL_VEL: intensity = len_v3(pa->state.vel) / part->color_vec_max; + CLAMP(intensity, 0.0f, 1.0f); + weight_to_rgb(ma_col, intensity); break; case PART_DRAW_COL_ACC: intensity = len_v3v3(pa->state.vel, pa->prev_state.vel) / ((pa->state.time - pa->prev_state.time) * part->color_vec_max); + CLAMP(intensity, 0.0f, 1.0f); + weight_to_rgb(ma_col, intensity); + break; + case PART_DRAW_COL_PARENT: + particle_path_color(a, ma_col); + break; + case PART_DRAW_COL_TEX: { + ParticleTexture ptex; + psys_get_texture(&sim, pa, &ptex, PAMAP_COLOR, cfra); + copy_v3_v3(ma_col, ptex.color); break; + } default: - intensity = 1.0f; /* should never happen */ + weight_to_rgb(ma_col, 1.0f); BLI_assert(0); break; } - CLAMP(intensity, 0.0f, 1.0f); - weight_to_rgb(ma_col, intensity); } } else { @@ -5651,8 +6052,24 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv if (1) { //ob_dt > OB_WIRE) { glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel); if ((dflag & DRAW_CONSTCOLOR) == 0) { - if (part->draw_col == PART_DRAW_COL_MAT) { - glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col); + float col[3]; + + switch (part->draw_col) { + case PART_DRAW_COL_MAT: + glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col); + break; + case PART_DRAW_COL_PARENT: + /* this switches colors to each new parent because new hull children come first */ + if (cache[a]->hull_parent >= 0) { + particle_path_color(cache[a]->hull_parent, col); + glColor3fv(col); + } + break; + case PART_DRAW_COL_TEX: + // TODO + break; + default: + break; } } } @@ -7527,6 +7944,72 @@ static void draw_object_wire_color(Scene *scene, Base *base, unsigned char r_ob_ r_ob_wire_col[3] = 255; } + +static float draw_object_wire_grey = -1.0f; +void draw_object_bg_wire_color_set(const float color[3]) +{ + draw_object_wire_grey = rgb_to_grayscale(color); +} + + +static void tint_neg(float rgb[3], float fac) +{ + mul_v3_fl(rgb, fac); +} + +static void tint_pos(float rgb[3], float fac) +{ + rgb[0] = 1.0 - rgb[0]; + rgb[1] = 1.0 - rgb[1]; + rgb[2] = 1.0 - rgb[2]; + + mul_v3_fl(rgb, fac); + + rgb[0] = 1.0 - rgb[0]; + rgb[1] = 1.0 - rgb[1]; + rgb[2] = 1.0 - rgb[2]; +} + +static void draw_object_wire_color_adjust_contrast( + unsigned char ob_wire_col[3], + /* 0 == normal, 1 == select, 2 == obact */ + const int select_state, + const short draw_type) +{ + float rgb[3]; + + BLI_assert(draw_object_wire_grey != -1.0); + + rgb_uchar_to_float(rgb, ob_wire_col); + + if (select_state == 0) { + tint_neg(rgb, 0.5f); + } + else { + tint_pos(rgb, select_state == 2 ? 0.15f : 0.35f); + } + + + /* when no solid --- ensure contrast */ + if (draw_type <= OB_WIRE) { + const float contrast = 0.1f; + + const float fill_bw = draw_object_wire_grey; + const float wire_bw = rgb_to_grayscale(rgb); + const float delta = wire_bw - fill_bw; + + if (fabsf(delta) < contrast) { + if (delta > 0.0f) { + add_v3_fl(rgb, (contrast - delta) / 2.0f); + } + else { + add_v3_fl(rgb, (contrast + delta) / -2.0f); + } + } + } + rgb_float_to_uchar(ob_wire_col, rgb); +} + static void draw_object_matcap_check(View3D *v3d, Object *ob) { /* fixed rule, active object draws as matcap */ @@ -7613,8 +8096,10 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short bool zbufoff = false, is_paint = false, empty_object = false; const bool is_obact = (ob == OBACT); const bool render_override = (v3d->flag2 & V3D_RENDER_OVERRIDE) != 0; + const bool show_motionpaths = !(v3d->flag3 & V3D_HIDE_MOTIONPATHS) != 0; const bool is_picking = (G.f & G_PICKSEL) != 0; const bool has_particles = (ob->particlesystem.first != NULL); + const bool is_wire_color = V3D_IS_WIRECOLOR_OBJECT(scene, v3d, ob); bool skip_object = false; /* Draw particles but not their emitter object. */ SmokeModifierData *smd = NULL; @@ -7701,34 +8186,36 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short view3d_cached_text_draw_begin(); /* draw motion paths (in view space) */ - if (ob->mpath && !render_override) { - bAnimVizSettings *avs = &ob->avs; - - /* setup drawing environment for paths */ - draw_motion_paths_init(v3d, ar); - - /* draw motion path for object */ - draw_motion_path_instance(scene, ob, NULL, avs, ob->mpath); - - /* cleanup after drawing */ - draw_motion_paths_cleanup(v3d); + if (ob->mpath && show_motionpaths && !(base->flag & OB_FROMDUPLI)) { + ED_view3d_after_add(&v3d->afterdraw_nodepth, base, 0); } - /* multiply view with object matrix. - * local viewmat and persmat, to calculate projections */ - ED_view3d_init_mats_rv3d_gl(ob, rv3d); - /* which wire color */ if ((dflag & DRAW_CONSTCOLOR) == 0) { ED_view3d_project_base(ar, base); - draw_object_wire_color(scene, base, _ob_wire_col); + if (is_wire_color) { + rgb_float_to_uchar(_ob_wire_col, ob->col); + _ob_wire_col[3] = 255; + + draw_object_wire_color_adjust_contrast( + _ob_wire_col, + (ob->flag & SELECT) ? (is_obact ? 2 : 1) : 0, + v3d->drawtype); + } + else { + draw_object_wire_color(scene, base, _ob_wire_col); + } ob_wire_col = _ob_wire_col; glColor3ubv(ob_wire_col); } + /* multiply view with object matrix. + * local viewmat and persmat, to calculate projections */ + ED_view3d_init_mats_rv3d_gl(ob, rv3d); + /* maximum drawtype */ dt = v3d->drawtype; if (dt == OB_RENDER) dt = OB_SOLID; @@ -7907,6 +8394,12 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short GPU_disable_material(); } } + /* draw motion paths if forced */ + if (show_motionpaths && !(dflag & DRAW_SCENESET)) { + bArmature *arm = ob->data; + if (!arm->edbo && !(base->flag & OB_FROMDUPLI)) + ED_view3d_after_add(&v3d->afterdraw_nodepth, base, 0); + } break; default: if (!render_override) { @@ -7941,7 +8434,8 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short /* code for new particle system */ if ((ob->particlesystem.first) && - (ob != scene->obedit)) + (ob != scene->obedit) && + !(ob->transflag & OB_IS_DUPLI_CACHE)) { ParticleSystem *psys; @@ -7958,14 +8452,16 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short view3d_cached_text_draw_begin(); for (psys = ob->particlesystem.first; psys; psys = psys->next) { - /* run this so that possible child particles get cached */ - if (ob->mode & OB_MODE_PARTICLE_EDIT && is_obact) { - PTCacheEdit *edit = PE_create_current(scene, ob); - if (edit && edit->psys == psys) - draw_update_ptcache_edit(scene, ob, edit); + if (!(ob->mode & OB_MODE_HAIR_EDIT)) { + /* run this so that possible child particles get cached */ + if (ob->mode & OB_MODE_PARTICLE_EDIT && is_obact) { + PTCacheEdit *edit = PE_create_current(scene, ob); + if (edit && edit->psys == psys) + draw_update_ptcache_edit(scene, ob, edit); + } + + draw_new_particle_system(scene, v3d, rv3d, base, psys, dt, dflag); } - - draw_new_particle_system(scene, v3d, rv3d, base, psys, dt, dflag); } invert_m4_m4(ob->imat, ob->obmat); view3d_cached_text_draw_end(v3d, ar, 0, NULL); @@ -7990,6 +8486,13 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short glMultMatrixf(ob->obmat); } } + + if (ob->mode & OB_MODE_HAIR_EDIT && is_obact) { + BMEditStrands *edit = BKE_editstrands_from_object(ob); + if (edit) { + draw_strands_edit_hair(scene, v3d, ar, edit); + } + } } /* draw code for smoke */ @@ -8050,12 +8553,37 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short BKE_boundbox_init_from_minmax(&bb, sds->p0, sds->p1); draw_box(bb.vec); #endif + + /* draw a single voxel to hint the user about the resolution of the fluid */ + copy_v3_v3(p0, sds->p0); + + if (sds->flags & MOD_SMOKE_HIGHRES) { + madd_v3_v3v3fl(p1, p0, sds->cell_size, 1.0f / (sds->amplify + 1)); + } + else { + add_v3_v3v3(p1, p0, sds->cell_size); + } + + BKE_boundbox_init_from_minmax(&bb, p0, p1); + draw_box(bb.vec, false); + +#ifdef WITH_OPENVDB + glLoadMatrixf(rv3d->viewmat); + if (sds->density) + OpenVDB_draw_primitive(sds->density, true, true, true, true); + if (sds->density_high) + OpenVDB_draw_primitive(sds->density_high, true, true, true, true); + glMultMatrixf(sds->fluidmat); +#endif } /* don't show smoke before simulation starts, this could be made an option in the future */ if (smd->domain->fluid && CFRA >= smd->domain->point_cache[0]->startframe) { float p0[3], p1[3]; + glLoadMatrixf(rv3d->viewmat); + glMultMatrixf(ob->obmat); + /* get view vector */ invert_m4_m4(ob->imat, ob->obmat); mul_v3_mat3_m4v3(viewnormal, ob->imat, rv3d->viewinv[2]); @@ -8195,7 +8723,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short } /* object centers, need to be drawn in viewmat space for speed, but OK for picking select */ - if (!is_obact || !(ob->mode & OB_MODE_ALL_PAINT)) { + if (!is_obact || !(ob->mode & OB_MODE_ALL_BRUSH)) { int do_draw_center = -1; /* defines below are zero or positive... */ if (render_override) { @@ -8658,6 +9186,48 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r if (dm) dm->release(dm); } +void ED_draw_object_facemap(Scene *scene, struct Object *ob, int facemap) +{ + DerivedMesh *dm = NULL; + + dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); + if (!dm || !CustomData_has_layer(&dm->polyData, CD_FACEMAP)) + return; + + DM_update_materials(dm, ob); + + glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); + + /* add polygon offset so we draw above the original surface */ + glPolygonOffset(1.0, 1.0); + + dm->totfmaps = BLI_listbase_count(&ob->fmaps); + + GPU_facemap_setup(dm); + + glColor4f(0.7, 1.0, 1.0, 0.5); + + glPushAttrib(GL_ENABLE_BIT); + glEnable(GL_BLEND); + glDisable(GL_LIGHTING); + + if (dm->drawObject->facemapindices) { + if (dm->drawObject->facemapindices->use_vbo) + glDrawElements(GL_TRIANGLES, dm->drawObject->facemap_count[facemap], GL_UNSIGNED_INT, + (int *)NULL + dm->drawObject->facemap_start[facemap]); + else + glDrawElements(GL_TRIANGLES, dm->drawObject->facemap_count[facemap], GL_UNSIGNED_INT, + (int *)dm->drawObject->facemapindices->pointer + dm->drawObject->facemap_start[facemap]); + } + glPopAttrib(); + + GPU_buffer_unbind(); + + glPolygonOffset(0.0, 0.0); + dm->release(dm); +} + + void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, const char dt, int outline) { if (ob == NULL) |