[Bf-blender-cvs] [0f1f3ca] fracture_modifier: first attempt to multithread fracturing, works only for prefractured for now
Martin Felke
noreply at git.blender.org
Mon Aug 8 00:37:30 CEST 2016
Commit: 0f1f3ca29278e04417613b846a99df78b9d1ac49
Author: Martin Felke
Date: Mon Aug 8 00:37:08 2016 +0200
Branches: fracture_modifier
https://developer.blender.org/rB0f1f3ca29278e04417613b846a99df78b9d1ac49
first attempt to multithread fracturing, works only for prefractured for now
===================================================================
M source/blender/blenkernel/intern/fracture.c
===================================================================
diff --git a/source/blender/blenkernel/intern/fracture.c b/source/blender/blenkernel/intern/fracture.c
index bd69896..c6b6b1f 100644
--- a/source/blender/blenkernel/intern/fracture.c
+++ b/source/blender/blenkernel/intern/fracture.c
@@ -56,6 +56,7 @@
#include "BLI_rand.h"
#include "BLI_string.h"
#include "BLI_sort.h"
+#include "BLI_task.h"
#include "BLI_utildefines.h"
#include "DNA_scene_types.h"
@@ -803,9 +804,10 @@ static void do_prepare_cells(FracMesh *fm, cell *cells, int expected_shards, int
/* parse the voro++ cell data */
+//static ThreadMutex prep_lock = BLI_MUTEX_INITIALIZER;
static void parse_cells(cell *cells, int expected_shards, ShardID parent_id, FracMesh *fm, int algorithm, Object *obj, DerivedMesh *dm,
short inner_material_index, float mat[4][4], int num_cuts, float fractal, bool smooth, int num_levels, int mode,
- bool reset, int active_setting, int num_settings, char uv_layer[64])
+ bool reset, int active_setting, int num_settings, char uv_layer[64], bool threaded)
{
/*Parse voronoi raw data*/
int i = 0, j = 0, count = 0;
@@ -839,7 +841,7 @@ static void parse_cells(cell *cells, int expected_shards, ShardID parent_id, Fra
return;
}
- if (mode == MOD_FRACTURE_PREFRACTURED && reset)
+ if (mode == MOD_FRACTURE_PREFRACTURED && reset && !threaded)
{
while (fm->shard_map.first)
{
@@ -1523,6 +1525,71 @@ void BKE_fracture_shard_by_planes(FractureModifierData *fmd, Object *obj, short
}
}
+typedef struct FractureData {
+ cell *voro_cells;
+ FracMesh *fmesh;
+ ShardID id;
+ int totpoints;
+ int algorithm;
+ Object *obj;
+ DerivedMesh *dm;
+ short inner_material_index;
+ float mat[4][4];
+ int num_cuts;
+ float fractal;
+ bool smooth;
+ int num_levels;
+ int mode;
+ bool reset;
+ int active_setting;
+ int num_settings;
+ char uv_layer[64];
+} FractureData;
+
+
+static void compute_fracture(TaskPool *UNUSED(pool), void *taskdata, int UNUSED(threadid))
+{
+ FractureData *fd = (FractureData*)taskdata;
+
+ /*Evaluate result*/
+ if (fd->totpoints > 0) {
+ parse_cells(fd->voro_cells, fd->totpoints, fd->id, fd->fmesh, fd->algorithm, fd->obj, fd->dm, fd->inner_material_index, fd->mat,
+ fd->num_cuts, fd->fractal, fd->smooth, fd->num_levels,fd->mode, fd->reset, fd->active_setting, fd->num_settings, fd->uv_layer,
+ true);
+ }
+}
+
+
+static FractureData segment_cells(cell *voro_cells, int startcell, int totcells, FracMesh *fmesh, ShardID id, FracPointCloud *pointcloud,
+ int algorithm, Object *obj, DerivedMesh *dm, short
+ inner_material_index, float mat[4][4], int num_cuts, float fractal, bool smooth, int num_levels, int mode,
+ bool reset, int active_setting, int num_settings, char uv_layer[64])
+{
+ FractureData fd;
+ fd.fmesh = fmesh;
+ fd.id = id;
+ fd.totpoints = totcells;
+ fd.algorithm = algorithm;
+ fd.obj = obj;
+ fd.dm = dm;
+ fd.inner_material_index = inner_material_index;
+ copy_m4_m4(fd.mat, mat);
+ fd.num_cuts = num_cuts;
+ fd.fractal = fractal;
+ fd.smooth = smooth;
+ fd.num_levels = num_levels;
+ fd.mode = mode;
+ fd.reset = reset;
+ fd.active_setting = active_setting;
+ fd.num_settings = num_settings;
+ strncpy(fd.uv_layer, uv_layer, 64);
+
+ //cell start pointer, only take fd.totpoints cells out
+ fd.voro_cells = voro_cells + startcell;
+
+ return fd;
+}
+
void BKE_fracture_shard_by_points(FracMesh *fmesh, ShardID id, FracPointCloud *pointcloud, int algorithm, Object *obj, DerivedMesh *dm, short
inner_material_index, float mat[4][4], int num_cuts, float fractal, bool smooth, int num_levels, int mode,
bool reset, int active_setting, int num_settings, char uv_layer[64])
@@ -1533,12 +1600,16 @@ void BKE_fracture_shard_by_points(FracMesh *fmesh, ShardID id, FracPointCloud *p
float min[3], max[3];
float theta = 0.1f; /* TODO, container enlargement, because boundbox exact container and boolean might create artifacts */
- int p;
+ int p, i = 0, num = 0, totcell = 0, remainder_start = 0;
container *voro_container;
particle_order *voro_particle_order;
cell *voro_cells;
+ TaskScheduler *scheduler = BLI_task_scheduler_get();
+ TaskPool *pool;
+ FractureData *fdata;
+
#ifdef USE_DEBUG_TIMER
double time_start;
#endif
@@ -1581,8 +1652,6 @@ void BKE_fracture_shard_by_points(FracMesh *fmesh, ShardID id, FracPointCloud *p
float *co = pointcloud->points[p].co;
container_put(voro_container, voro_particle_order, p, co[0], co[1], co[2]);
}
-
-
#ifdef USE_DEBUG_TIMER
time_start = PIL_check_seconds_timer();
@@ -1594,9 +1663,43 @@ void BKE_fracture_shard_by_points(FracMesh *fmesh, ShardID id, FracPointCloud *p
/*Compute directly...*/
container_compute_cells(voro_container, voro_cells);
- /*Evaluate result*/
- parse_cells(voro_cells, pointcloud->totpoints, id, fmesh, algorithm, obj, dm, inner_material_index, mat,
- num_cuts, fractal, smooth, num_levels, mode, reset, active_setting, num_settings, uv_layer);
+ if (mode != MOD_FRACTURE_DYNAMIC) {
+ /*segment cells, give each thread a chunk to work on */
+ pool = BLI_task_pool_create(scheduler, NULL);
+ num = BLI_task_scheduler_num_threads(scheduler);
+ fdata = MEM_callocN(sizeof(FractureData) * (num + 1), "threaded fracture data");
+ totcell = pointcloud->totpoints / num;
+ for (i = 0; i < num; i++) {
+ //give each task a segment of the shards...
+ int startcell = i * totcell;
+ FractureData fd = segment_cells(voro_cells, startcell, totcell, fmesh, id, pointcloud, algorithm, obj, dm, inner_material_index,
+ mat, num_cuts, fractal,smooth, num_levels, mode, reset, active_setting, num_settings, uv_layer);
+ fdata[i] = fd;
+ }
+
+ //remainder...
+ remainder_start = fdata[0].totpoints * num;
+ if (remainder_start < pointcloud->totpoints) {
+ int remainder = pointcloud->totpoints - remainder_start;
+ int startcell = remainder_start;
+ printf("REMAINDER %d %d\n", startcell, remainder);
+ fdata[num] = segment_cells(voro_cells, startcell, remainder, fmesh, id, pointcloud, algorithm, obj, dm, inner_material_index,
+ mat, num_cuts, fractal,smooth, num_levels, mode, reset, active_setting, num_settings, uv_layer);
+ }
+
+ for (i = 0; i < num+1; i++) {
+ BLI_task_pool_push(pool, compute_fracture, &fdata[i], false, TASK_PRIORITY_HIGH);
+ }
+
+ BLI_task_pool_work_and_wait(pool);
+ BLI_task_pool_free(pool);
+ MEM_freeN(fdata);
+ }
+ else {
+ /*Evaluate result*/
+ parse_cells(voro_cells, pointcloud->totpoints, id, fmesh, algorithm, obj, dm, inner_material_index, mat,
+ num_cuts, fractal, smooth, num_levels, mode, reset, active_setting, num_settings, uv_layer, false);
+ }
/*Free structs in C++ area of memory */
cells_free(voro_cells, pointcloud->totpoints);
More information about the Bf-blender-cvs
mailing list