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:
Diffstat (limited to 'source/blender/editors/space_view3d/drawobject.c')
-rw-r--r--source/blender/editors/space_view3d/drawobject.c662
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)