Fix T47189: Large smoke simulation sometimes make Blender crash.
authorBastien Montagne <montagne29@wanadoo.fr>
Sat, 16 Jan 2016 21:37:34 +0000 (22:37 +0100)
committerBastien Montagne <montagne29@wanadoo.fr>
Sat, 16 Jan 2016 21:45:04 +0000 (22:45 +0100)
Issue was with very thin domains along one or two axes, these could lead to simulation
with only one cell width - and smoke code assumes we have at least 4 cells in each direction.

So now, we clamp resolution to a minimum of 4 in smoke_set_domain_from_derivedmesh().

Note: in extreme cases like this report, this will generate very un-cubic cells,
check it still works OK in 3DView is needed here.

Thanks to @genscher and @kevindietrich for help on this issue. :)

source/blender/blenkernel/intern/smoke.c

index f5a6644e1bb8f3ce85aeb72b2e95f1c2fd81753d..2d3fa2a381832567a28934031363c10689d5f3c7 100644 (file)
@@ -246,21 +246,21 @@ static void smoke_set_domain_from_derivedmesh(SmokeDomainSettings *sds, Object *
                scale = res / size[0];
                sds->scale = size[0] / fabsf(ob->size[0]);
                sds->base_res[0] = res;
-               sds->base_res[1] = (int)(size[1] * scale + 0.5f);
-               sds->base_res[2] = (int)(size[2] * scale + 0.5f);
+               sds->base_res[1] = max_ii((int)(size[1] * scale + 0.5f), 4);
+               sds->base_res[2] = max_ii((int)(size[2] * scale + 0.5f), 4);
        }
        else if (size[1] >= MAX2(size[0], size[2])) {
                scale = res / size[1];
                sds->scale = size[1] / fabsf(ob->size[1]);
-               sds->base_res[0] = (int)(size[0] * scale + 0.5f);
+               sds->base_res[0] = max_ii((int)(size[0] * scale + 0.5f), 4);
                sds->base_res[1] = res;
-               sds->base_res[2] = (int)(size[2] * scale + 0.5f);
+               sds->base_res[2] = max_ii((int)(size[2] * scale + 0.5f), 4);
        }
        else {
                scale = res / size[2];
                sds->scale = size[2] / fabsf(ob->size[2]);
-               sds->base_res[0] = (int)(size[0] * scale + 0.5f);
-               sds->base_res[1] = (int)(size[1] * scale + 0.5f);
+               sds->base_res[0] = max_ii((int)(size[0] * scale + 0.5f), 4);
+               sds->base_res[1] = max_ii((int)(size[1] * scale + 0.5f), 4);
                sds->base_res[2] = res;
        }