[Bf-blender-cvs] [4446acb] master: Viewport smoke: add support for axis aligned slicing.

Kévin Dietrich noreply at git.blender.org
Sat Sep 24 22:38:56 CEST 2016


Commit: 4446acbf17748f30b163016cfc4b88bba8653517
Author: Kévin Dietrich
Date:   Sat Sep 24 21:41:16 2016 +0200
Branches: master
https://developer.blender.org/rB4446acbf17748f30b163016cfc4b88bba8653517

Viewport smoke: add support for axis aligned slicing.

Current approach uses view aligned slicing to generate polygons for GL
texturing such that the generated polygons are always facing the view
plane. Now it is also possible to use object aligned slicing, which
creates polygons by slicing the object perpendicular to whichever axis
is facing the most the view plane. It is also possible to create a
single slice for inspecting the volume, or for 2D rendering effects.

Settings for this, along with a density multiplier setting, are to be
found in a newly added "Smoke Display Settings" panel in the smoke
domain properties tab.

Reviewers: plasmasolutions, gottfried

Differential Revision: https://developer.blender.org/D1733

===================================================================

M	release/scripts/startup/bl_ui/properties_physics_smoke.py
M	source/blender/blenkernel/intern/smoke.c
M	source/blender/blenloader/intern/versioning_270.c
M	source/blender/editors/space_view3d/drawvolume.c
M	source/blender/makesdna/DNA_smoke_types.h
M	source/blender/makesrna/intern/rna_smoke.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/properties_physics_smoke.py b/release/scripts/startup/bl_ui/properties_physics_smoke.py
index 99aa54a..829850e 100644
--- a/release/scripts/startup/bl_ui/properties_physics_smoke.py
+++ b/release/scripts/startup/bl_ui/properties_physics_smoke.py
@@ -349,5 +349,40 @@ class PHYSICS_PT_smoke_field_weights(PhysicButtonsPanel, Panel):
         domain = context.smoke.domain_settings
         effector_weights_ui(self, context, domain.effector_weights, 'SMOKE')
 
+
+class PHYSICS_PT_smoke_display_settings(PhysicButtonsPanel, Panel):
+    bl_label = "Smoke Display Settings"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    @classmethod
+    def poll(cls, context):
+        md = context.smoke
+        rd = context.scene.render
+        return md and (md.smoke_type == 'DOMAIN') and (not rd.use_game_engine)
+
+    def draw(self, context):
+        domain = context.smoke.domain_settings
+        layout = self.layout
+
+        layout.prop(domain, "display_thickness")
+
+        layout.separator()
+        layout.label(text="Slicing:")
+        layout.prop(domain, "slice_method")
+
+        slice_method = domain.slice_method
+        axis_slice_method = domain.axis_slice_method
+
+        if slice_method == 'AXIS_ALIGNED':
+            layout.prop(domain, "axis_slice_method")
+
+            if axis_slice_method == 'SINGLE':
+                layout.prop(domain, "slice_axis")
+                layout.prop(domain, "slice_depth")
+
+        if axis_slice_method == 'FULL':
+            layout.prop(domain, "slice_per_voxel")
+
+
 if __name__ == "__main__":  # only for live edit.
     bpy.utils.register_module(__name__)
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index f622d54..d0f546e 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -536,6 +536,13 @@ void smokeModifier_createType(struct SmokeModifierData *smd)
 #endif
 			smd->domain->data_depth = 0;
 			smd->domain->cache_file_format = PTCACHE_FILE_PTCACHE;
+
+			smd->domain->display_thickness = 1.0f;
+			smd->domain->slice_method = MOD_SMOKE_SLICE_VIEW_ALIGNED;
+			smd->domain->axis_slice_method = AXIS_SLICE_FULL;
+			smd->domain->slice_per_voxel = 5.0f;
+			smd->domain->slice_depth = 0.5f;
+			smd->domain->slice_axis = 0;
 		}
 		else if (smd->type & MOD_SMOKE_TYPE_FLOW)
 		{
@@ -629,6 +636,12 @@ void smokeModifier_copy(struct SmokeModifierData *smd, struct SmokeModifierData
 		tsmd->domain->openvdb_comp = smd->domain->openvdb_comp;
 		tsmd->domain->data_depth = smd->domain->data_depth;
 		tsmd->domain->cache_file_format = smd->domain->cache_file_format;
+
+		tsmd->domain->slice_method = smd->domain->slice_method;
+		tsmd->domain->axis_slice_method = smd->domain->axis_slice_method;
+		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;
 	}
 	else if (tsmd->flow) {
 		tsmd->flow->psys = smd->flow->psys;
diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c
index aa5ef1c..0d4ff00 100644
--- a/source/blender/blenloader/intern/versioning_270.c
+++ b/source/blender/blenloader/intern/versioning_270.c
@@ -52,6 +52,7 @@
 #include "DNA_linestyle_types.h"
 #include "DNA_actuator_types.h"
 #include "DNA_view3d_types.h"
+#include "DNA_smoke_types.h"
 
 #include "DNA_genfile.h"
 
@@ -1405,5 +1406,23 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
 				scene->r.ffcodecdata.constant_rate_factor = FFM_CRF_NONE;
 			}
 		}
+
+		if (!DNA_struct_elem_find(fd->filesdna, "SmokeModifierData", "float", "slice_per_voxel")) {
+			Object *ob;
+			ModifierData *md;
+
+			for (ob = main->object.first; ob; ob = ob->id.next) {
+				for (md = ob->modifiers.first; md; md = md->next) {
+					if (md->type == eModifierType_Smoke) {
+						SmokeModifierData *smd = (SmokeModifierData *)md;
+						if (smd->domain) {
+							smd->domain->slice_per_voxel = 5.0f;
+							smd->domain->slice_depth = 0.5f;
+							smd->domain->display_thickness = 1.0f;
+						}
+					}
+				}
+			}
+		}
 	}
 }
diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c
index 06677ef..d743e7c 100644
--- a/source/blender/editors/space_view3d/drawvolume.c
+++ b/source/blender/editors/space_view3d/drawvolume.c
@@ -113,6 +113,63 @@ typedef struct VolumeSlicer {
 	float (*verts)[3];
 } VolumeSlicer;
 
+/* *************************** Axis Aligned Slicing ************************** */
+
+static void create_single_slice(VolumeSlicer *slicer, const float depth,
+                                const int axis, const int idx)
+{
+	const float vertices[3][4][3] = {
+	    {
+	        { depth, slicer->min[1], slicer->min[2] },
+	        { depth, slicer->max[1], slicer->min[2] },
+	        { depth, slicer->max[1], slicer->max[2] },
+	        { depth, slicer->min[1], slicer->max[2] }
+	    },
+	    {
+	        { slicer->min[0], depth, slicer->min[2] },
+	        { slicer->min[0], depth, slicer->max[2] },
+	        { slicer->max[0], depth, slicer->max[2] },
+	        { slicer->max[0], depth, slicer->min[2] }
+	    },
+	    {
+	        { slicer->min[0], slicer->min[1], depth },
+	        { slicer->min[0], slicer->max[1], depth },
+	        { slicer->max[0], slicer->max[1], depth },
+	        { slicer->max[0], slicer->min[1], depth }
+	    }
+	};
+
+	copy_v3_v3(slicer->verts[idx + 0], vertices[axis][0]);
+	copy_v3_v3(slicer->verts[idx + 1], vertices[axis][1]);
+	copy_v3_v3(slicer->verts[idx + 2], vertices[axis][2]);
+	copy_v3_v3(slicer->verts[idx + 3], vertices[axis][0]);
+	copy_v3_v3(slicer->verts[idx + 4], vertices[axis][2]);
+	copy_v3_v3(slicer->verts[idx + 5], vertices[axis][3]);
+}
+
+static void create_axis_aligned_slices(VolumeSlicer *slicer, const int num_slices,
+                                       const float view_dir[3], const int axis)
+{
+	float depth, slice_size = slicer->size[axis] / num_slices;
+
+	/* always process slices in back to front order! */
+	if (view_dir[axis] > 0.0f) {
+		depth = slicer->min[axis];
+	}
+	else {
+		depth = slicer->max[axis];
+		slice_size = -slice_size;
+	}
+
+	int count = 0;
+	for (int slice = 0; slice < num_slices; slice++) {
+		create_single_slice(slicer, depth, axis, count);
+
+		count += 6;
+		depth += slice_size;
+	}
+}
+
 /* *************************** View Aligned Slicing ************************** */
 
 /* Code adapted from:
@@ -433,8 +490,25 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
 
 	/* setup slicing information */
 
-	const int max_slices = 256;
-	const int max_points = max_slices * 12;
+	const bool view_aligned = (sds->slice_method == MOD_SMOKE_SLICE_VIEW_ALIGNED);
+	int max_slices, max_points, axis = 0;
+
+	if (view_aligned) {
+		max_slices = max_iii(sds->res[0], sds->res[1], sds->res[2]) * sds->slice_per_voxel;
+		max_points = max_slices * 12;
+	}
+	else {
+		if (sds->axis_slice_method == AXIS_SLICE_FULL) {
+			axis = axis_dominant_v3_single(viewnormal);
+			max_slices = sds->res[axis] * sds->slice_per_voxel;
+		}
+		else {
+			axis = (sds->slice_axis == SLICE_AXIS_AUTO) ? axis_dominant_v3_single(viewnormal) : sds->slice_axis - 1;
+			max_slices = 1;
+		}
+
+		max_points = max_slices * 6;
+	}
 
 	VolumeSlicer slicer;
 	copy_v3_v3(slicer.min, min);
@@ -442,7 +516,22 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
 	copy_v3_v3(slicer.size, size);
 	slicer.verts = MEM_mallocN(sizeof(float) * 3 * max_points, "smoke_slice_vertices");
 
-	const int num_points = create_view_aligned_slices(&slicer, max_slices, viewnormal);
+	int num_points;
+
+	if (view_aligned) {
+		num_points = create_view_aligned_slices(&slicer, max_slices, viewnormal);
+	}
+	else {
+		num_points = max_points;
+
+		if (sds->axis_slice_method == AXIS_SLICE_FULL) {
+			create_axis_aligned_slices(&slicer, max_slices, viewnormal, axis);
+		}
+		else {
+			const float depth = (sds->slice_depth - 0.5f) * size[axis];
+			create_single_slice(&slicer, depth, axis, 0);
+		}
+	}
 
 	/* setup buffer and draw */
 
diff --git a/source/blender/makesdna/DNA_smoke_types.h b/source/blender/makesdna/DNA_smoke_types.h
index 76de844..5526c18 100644
--- a/source/blender/makesdna/DNA_smoke_types.h
+++ b/source/blender/makesdna/DNA_smoke_types.h
@@ -52,6 +52,26 @@ enum {
 /* viewsettings */
 #define MOD_SMOKE_VIEW_SHOWBIG (1<<0)
 
+/* slice method */
+enum {
+	MOD_SMOKE_SLICE_VIEW_ALIGNED = 0,
+	MOD_SMOKE_SLICE_AXIS_ALIGNED = 1,
+};
+
+/* axis aligned method */
+enum {
+	AXIS_SLICE_FULL   = 0,
+	AXIS_SLICE_SINGLE = 1,
+};
+
+/* single slice direction */
+enum {
+	SLICE_AXIS_AUTO = 0,
+	SLICE_AXIS_X    = 1,
+	SLICE_AXIS_Y    = 2,
+	SLICE_AXIS_Z    = 3,
+};
+
 /* cache compression */
 #define SM_CACHE_LIGHT		0
 #define SM_CACHE_HEAVY		1
@@ -161,6 +181,13 @@ typedef struct SmokeDomainSettings {
 	float burning_rate, flame_smoke, flame_vorticity;
 	float flame_ignition, flame_max_temp;
 	float flame_smoke_color[3];
+
+	/* Display settings */
+	char slice_method, axis_slice_method;
+	char slice_axis, pad2;
+	float slice_per_voxel;
+	float slice_depth;
+	float display_thickness;
 } SmokeDomainSettings;
 
 
diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c
index dad5577..22c1a11 100644
--- a/source/blender/makesrna/intern/rna_smoke.c
+++ b/source/blender/makesrna/intern/rna_smoke.c
@@ -443,6 +443,26 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
 		{0, NULL, 0, NULL, NULL}
 	};
 
+	static EnumPropertyItem smoke_view_items[] = {
+	    {MOD_SMOKE_SLICE_VIEW_ALIGNED, "VIEW_ALIGNED", 0, "View", "Slice volume parallel to the view plane"},
+	    {MOD_SMOKE_SLICE_AXIS_ALIGNED, "AXIS_ALIGNED", 0, "Axis", "Slice volume parallel to the major axis"},
+	    {0, NULL, 0, NULL, NULL}
+	};
+
+	static EnumPropertyItem axis_slice_method_items[] = {
+	    {AXIS_SLICE_FULL, "FULL", 0, "Full", "Slice the whole domain object"},
+	    {AXIS_SLICE_SINGLE, "SINGLE", 0, "Single", "Perform a single slice of the domain object"},
+	    {0, NULL, 0, NULL, NULL}
+	};
+
+	static EnumPropertyItem axis_slice_position_items[] =

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list