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
path: root/source
diff options
context:
space:
mode:
authorKévin Dietrich <kevin.dietrich@mailoo.org>2016-09-24 23:36:54 +0300
committerKévin Dietrich <kevin.dietrich@mailoo.org>2016-09-24 23:36:54 +0300
commit14e825aa1fb57db85cecfda0cd69843b57cefd12 (patch)
treebc10d135f04acbba3266ff2da75caa0fd2dd3ff2 /source
parent4446acbf17748f30b163016cfc4b88bba8653517 (diff)
Viewport smoke: add options to draw velocity vectors.
This basically exposes to the UI a function that was only available through a debug macro ; the purpose is obviously to help debugging simulations. It adds ways to draw the vectors either as colored needles or as arrows showing the direction of the vectors. The colors are based on the magnitude of the underlying vectors. Reviewers: plasmasolutions, gottfried Differential Revision: https://developer.blender.org/D1733
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/smoke.c4
-rw-r--r--source/blender/editors/space_view3d/drawobject.c7
-rw-r--r--source/blender/editors/space_view3d/drawvolume.c204
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h6
-rw-r--r--source/blender/makesdna/DNA_smoke_types.h10
-rw-r--r--source/blender/makesrna/intern/rna_smoke.c24
6 files changed, 205 insertions, 50 deletions
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index d0f546e9bef..05540f51588 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -543,6 +543,7 @@ void smokeModifier_createType(struct SmokeModifierData *smd)
smd->domain->slice_per_voxel = 5.0f;
smd->domain->slice_depth = 0.5f;
smd->domain->slice_axis = 0;
+ smd->domain->vector_scale = 1.0f;
}
else if (smd->type & MOD_SMOKE_TYPE_FLOW)
{
@@ -642,6 +643,9 @@ void smokeModifier_copy(struct SmokeModifierData *smd, struct SmokeModifierData
tsmd->domain->slice_per_voxel = smd->domain->slice_per_voxel;
tsmd->domain->slice_depth = smd->domain->slice_depth;
tsmd->domain->slice_axis = smd->domain->slice_axis;
+ tsmd->domain->draw_velocity = smd->domain->draw_velocity;
+ tsmd->domain->vector_draw_type = smd->domain->vector_draw_type;
+ tsmd->domain->vector_scale = smd->domain->vector_scale;
}
else if (tsmd->flow) {
tsmd->flow->psys = smd->flow->psys;
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index a74c0f0f467..ea40d4eb5e1 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -7912,9 +7912,10 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
}
/* smoke debug render */
-#ifdef SMOKE_DEBUG_VELOCITY
- draw_smoke_velocity(smd->domain, ob);
-#endif
+ if (!render_override && sds->draw_velocity) {
+ draw_smoke_velocity(sds, viewnormal);
+ }
+
#ifdef SMOKE_DEBUG_HEAT
draw_smoke_heat(smd->domain, ob);
#endif
diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c
index d743e7c09e7..ef4db7ed6b8 100644
--- a/source/blender/editors/space_view3d/drawvolume.c
+++ b/source/blender/editors/space_view3d/drawvolume.c
@@ -40,6 +40,7 @@
#include "BLI_utildefines.h"
#include "BLI_math.h"
+#include "BKE_DerivedMesh.h"
#include "BKE_particle.h"
#include "smoke_API.h"
@@ -571,61 +572,180 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
}
}
-#ifdef SMOKE_DEBUG_VELOCITY
-void draw_smoke_velocity(SmokeDomainSettings *domain, Object *ob)
+static void add_tri(float (*verts)[3], float(*colors)[3], int *offset,
+ float p1[3], float p2[3], float p3[3], float rgb[3])
{
- float x, y, z;
- float x0, y0, z0;
- int *base_res = domain->base_res;
- int *res = domain->res;
- int *res_min = domain->res_min;
- int *res_max = domain->res_max;
- float *vel_x = smoke_get_velocity_x(domain->fluid);
- float *vel_y = smoke_get_velocity_y(domain->fluid);
- float *vel_z = smoke_get_velocity_z(domain->fluid);
+ copy_v3_v3(verts[*offset + 0], p1);
+ copy_v3_v3(verts[*offset + 1], p2);
+ copy_v3_v3(verts[*offset + 2], p3);
- float min[3];
- float *cell_size = domain->cell_size;
- float step_size = ((float)max_iii(base_res[0], base_res[1], base_res[2])) / 16.f;
- float vf = domain->scale / 16.f * 2.f; /* velocity factor */
+ copy_v3_v3(colors[*offset + 0], rgb);
+ copy_v3_v3(colors[*offset + 1], rgb);
+ copy_v3_v3(colors[*offset + 2], rgb);
- glLineWidth(1.0f);
+ *offset += 3;
+}
+
+static void add_needle(float (*verts)[3], float (*colors)[3], float center[3],
+ float dir[3], float scale, float voxel_size, int *offset)
+{
+ float len = len_v3(dir);
+
+ float rgb[3];
+ weight_to_rgb(rgb, len);
+
+ if (len != 0.0f) {
+ mul_v3_fl(dir, 1.0f / len);
+ len *= scale;
+ }
+
+ len *= voxel_size;
+
+ float corners[4][3] = {
+ { 0.0f, 0.2f, -0.5f },
+ { -0.2f * 0.866f, -0.2f * 0.5f, -0.5f },
+ { 0.2f * 0.866f, -0.2f * 0.5f, -0.5f },
+ { 0.0f, 0.0f, 0.5f }
+ };
+
+ const float up[3] = { 0.0f, 0.0f, 1.0f };
+ float rot[3][3];
+
+ rotation_between_vecs_to_mat3(rot, up, dir);
+ transpose_m3(rot);
+
+ for (int i = 0; i < 4; i++) {
+ mul_m3_v3(rot, corners[i]);
+ mul_v3_fl(corners[i], len);
+ add_v3_v3(corners[i], center);
+ }
+
+ add_tri(verts, colors, offset, corners[0], corners[1], corners[2], rgb);
+ add_tri(verts, colors, offset, corners[0], corners[1], corners[3], rgb);
+ add_tri(verts, colors, offset, corners[1], corners[2], corners[3], rgb);
+ add_tri(verts, colors, offset, corners[2], corners[0], corners[3], rgb);
+}
+
+static void add_streamline(float (*verts)[3], float(*colors)[3], float center[3],
+ float dir[3], float scale, float voxel_size, int *offset)
+{
+ const float len = len_v3(dir);
+
+ float rgb[3];
+ weight_to_rgb(rgb, len);
+
+ copy_v3_v3(colors[(*offset)], rgb);
+ copy_v3_v3(verts[(*offset)++], center);
+
+ mul_v3_fl(dir, scale * voxel_size);
+ add_v3_v3(center, dir);
+
+ copy_v3_v3(colors[(*offset)], rgb);
+ copy_v3_v3(verts[(*offset)++], center);
+}
+
+typedef void (*vector_draw_func)(float(*)[3], float(*)[3], float*, float*, float, float, int*);
+
+void draw_smoke_velocity(SmokeDomainSettings *domain, float viewnormal[3])
+{
+ const int *base_res = domain->base_res;
+ const int *res = domain->res;
+ const int *res_min = domain->res_min;
+
+ int res_max[3];
+ copy_v3_v3_int(res_max, domain->res_max);
+
+ const float *vel_x = smoke_get_velocity_x(domain->fluid);
+ const float *vel_y = smoke_get_velocity_y(domain->fluid);
+ const float *vel_z = smoke_get_velocity_z(domain->fluid);
+
+ const float *cell_size = domain->cell_size;
+ const float step_size = ((float)max_iii(base_res[0], base_res[1], base_res[2])) / 16.0f;
/* set first position so that it doesn't jump when domain moves */
- x0 = res_min[0] + fmod(-(float)domain->shift[0] + res_min[0], step_size);
- y0 = res_min[1] + fmod(-(float)domain->shift[1] + res_min[1], step_size);
- z0 = res_min[2] + fmod(-(float)domain->shift[2] + res_min[2], step_size);
- if (x0 < res_min[0]) x0 += step_size;
- if (y0 < res_min[1]) y0 += step_size;
- if (z0 < res_min[2]) z0 += step_size;
+ float xyz[3] = {
+ res_min[0] + fmod(-(float)domain->shift[0] + res_min[0], step_size),
+ res_min[1] + fmod(-(float)domain->shift[1] + res_min[1], step_size),
+ res_min[2] + fmod(-(float)domain->shift[2] + res_min[2], step_size)
+ };
+
+ if (xyz[0] < res_min[0]) xyz[0] += step_size;
+ if (xyz[1] < res_min[1]) xyz[1] += step_size;
+ if (xyz[2] < res_min[2]) xyz[2] += step_size;
+
+ float min[3];
add_v3_v3v3(min, domain->p0, domain->obj_shift_f);
- for (x = floor(x0); x < res_max[0]; x += step_size)
- for (y = floor(y0); y < res_max[1]; y += step_size)
- for (z = floor(z0); z < res_max[2]; z += step_size) {
+ int num_points_v[3] = {
+ ((float)(res_max[0] - floor(xyz[0])) / step_size) + 0.5f,
+ ((float)(res_max[1] - floor(xyz[1])) / step_size) + 0.5f,
+ ((float)(res_max[2] - floor(xyz[2])) / step_size) + 0.5f
+ };
+
+ if (domain->slice_method == MOD_SMOKE_SLICE_AXIS_ALIGNED &&
+ domain->axis_slice_method == AXIS_SLICE_SINGLE)
+ {
+ const int axis = (domain->slice_axis == SLICE_AXIS_AUTO) ?
+ axis_dominant_v3_single(viewnormal) : domain->slice_axis - 1;
+
+ xyz[axis] = (float)res[axis] * domain->slice_depth;
+ num_points_v[axis] = 1;
+ res_max[axis] = xyz[axis] + 1;
+ }
+
+ vector_draw_func func;
+ int max_points;
+
+ if (domain->vector_draw_type == VECTOR_DRAW_NEEDLE) {
+ func = add_needle;
+ max_points = (num_points_v[0] * num_points_v[1] * num_points_v[2]) * 4 * 3;
+ }
+ else {
+ func = add_streamline;
+ max_points = (num_points_v[0] * num_points_v[1] * num_points_v[2]) * 2;
+ }
+
+ float (*verts)[3] = MEM_mallocN(sizeof(float) * 3 * max_points, "");
+ float (*colors)[3] = MEM_mallocN(sizeof(float) * 3 * max_points, "");
+
+ int num_points = 0;
+
+ for (float x = floor(xyz[0]); x < res_max[0]; x += step_size) {
+ for (float y = floor(xyz[1]); y < res_max[1]; y += step_size) {
+ for (float z = floor(xyz[2]); z < res_max[2]; z += step_size) {
int index = (floor(x) - res_min[0]) + (floor(y) - res_min[1]) * res[0] + (floor(z) - res_min[2]) * res[0] * res[1];
- float pos[3] = {min[0] + ((float)x + 0.5f) * cell_size[0], min[1] + ((float)y + 0.5f) * cell_size[1], min[2] + ((float)z + 0.5f) * cell_size[2]};
- float vel = sqrtf(vel_x[index] * vel_x[index] + vel_y[index] * vel_y[index] + vel_z[index] * vel_z[index]);
+ float pos[3] = {
+ min[0] + ((float)x + 0.5f) * cell_size[0],
+ min[1] + ((float)y + 0.5f) * cell_size[1],
+ min[2] + ((float)z + 0.5f) * cell_size[2]
+ };
- /* draw heat as scaled "arrows" */
- if (vel >= 0.01f) {
- float col_g = 1.0f - vel;
- CLAMP(col_g, 0.0f, 1.0f);
- glColor3f(1.0f, col_g, 0.0f);
- glPointSize(10.0f * vel);
+ float vel[3] = {
+ vel_x[index], vel_y[index], vel_z[index]
+ };
- glBegin(GL_LINES);
- glVertex3f(pos[0], pos[1], pos[2]);
- glVertex3f(pos[0] + vel_x[index] * vf, pos[1] + vel_y[index] * vf, pos[2] + vel_z[index] * vf);
- glEnd();
- glBegin(GL_POINTS);
- glVertex3f(pos[0] + vel_x[index] * vf, pos[1] + vel_y[index] * vf, pos[2] + vel_z[index] * vf);
- glEnd();
- }
+ func(verts, colors, pos, vel, domain->vector_scale, cell_size[0], &num_points);
}
+ }
+ }
+
+ glLineWidth(1.0f);
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(3, GL_FLOAT, 0, verts);
+
+ glEnableClientState(GL_COLOR_ARRAY);
+ glColorPointer(3, GL_FLOAT, 0, colors);
+
+ glDrawArrays(GL_LINES, 0, num_points);
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+
+ MEM_freeN(verts);
+ MEM_freeN(colors);
}
-#endif
#ifdef SMOKE_DEBUG_HEAT
void draw_smoke_heat(SmokeDomainSettings *domain, Object *ob)
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 314dadbaa52..0e2cb95dd89 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -296,12 +296,10 @@ void draw_smoke_volume(struct SmokeDomainSettings *sds, struct Object *ob,
const float min[3], const float max[3],
const float viewnormal[3]);
-//#define SMOKE_DEBUG_VELOCITY
//#define SMOKE_DEBUG_HEAT
-#ifdef SMOKE_DEBUG_VELOCITY
-void draw_smoke_velocity(struct SmokeDomainSettings *domain, struct Object *ob);
-#endif
+void draw_smoke_velocity(struct SmokeDomainSettings *domain, float viewnormal[3]);
+
#ifdef SMOKE_DEBUG_HEAT
void draw_smoke_heat(struct SmokeDomainSettings *domain, struct Object *ob);
#endif
diff --git a/source/blender/makesdna/DNA_smoke_types.h b/source/blender/makesdna/DNA_smoke_types.h
index 5526c18f656..ba7f73c2f63 100644
--- a/source/blender/makesdna/DNA_smoke_types.h
+++ b/source/blender/makesdna/DNA_smoke_types.h
@@ -72,6 +72,11 @@ enum {
SLICE_AXIS_Z = 3,
};
+enum {
+ VECTOR_DRAW_NEEDLE = 0,
+ VECTOR_DRAW_STREAMLINE = 1,
+};
+
/* cache compression */
#define SM_CACHE_LIGHT 0
#define SM_CACHE_HEAVY 1
@@ -184,10 +189,13 @@ typedef struct SmokeDomainSettings {
/* Display settings */
char slice_method, axis_slice_method;
- char slice_axis, pad2;
+ char slice_axis, draw_velocity;
float slice_per_voxel;
float slice_depth;
float display_thickness;
+ float vector_scale;
+ char vector_draw_type;
+ char pad2[3];
} SmokeDomainSettings;
diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c
index 22c1a115a15..40a45416aca 100644
--- a/source/blender/makesrna/intern/rna_smoke.c
+++ b/source/blender/makesrna/intern/rna_smoke.c
@@ -463,6 +463,12 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem vector_draw_items[] = {
+ {VECTOR_DRAW_NEEDLE, "NEEDLE", 0, "Needle", "Draw vectors as needles"},
+ {VECTOR_DRAW_STREAMLINE, "STREAMLINE", 0, "Streamlines", "Draw vectors as streamlines"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
srna = RNA_def_struct(brna, "SmokeDomainSettings", NULL);
RNA_def_struct_ui_text(srna, "Domain Settings", "Smoke domain settings");
RNA_def_struct_sdna(srna, "SmokeDomainSettings");
@@ -781,6 +787,24 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 0.1, 100.0, 0.1, 3);
RNA_def_property_ui_text(prop, "Thickness", "Thickness of smoke drawing in the viewport");
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, NULL);
+
+ prop = RNA_def_property(srna, "draw_velocity", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "draw_velocity", 0);
+ RNA_def_property_ui_text(prop, "Draw Velocity", "Toggle visualation of the velocity field as needles");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
+
+ prop = RNA_def_property(srna, "vector_draw_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "vector_draw_type");
+ RNA_def_property_enum_items(prop, vector_draw_items);
+ RNA_def_property_ui_text(prop, "Draw Type", "");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
+
+ prop = RNA_def_property(srna, "vector_scale", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "vector_scale");
+ RNA_def_property_range(prop, 0.0, 1000.0);
+ RNA_def_property_ui_range(prop, 0.0, 100.0, 0.1, 3);
+ RNA_def_property_ui_text(prop, "Scale", "Multiplier for scaling the vectors");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
}
static void rna_def_smoke_flow_settings(BlenderRNA *brna)