[Bf-extensions-cvs] [e25bc52] master: Generic progress report system with optional stdout and wm.progress output.
Lukas Tönne
noreply at git.blender.org
Mon Dec 15 14:31:36 CET 2014
Commit: e25bc52dbebc5a189b6f253c634fd97042713d69
Author: Lukas Tönne
Date: Mon Dec 15 14:28:17 2014 +0100
Branches: master
https://developer.blender.org/rBACe25bc52dbebc5a189b6f253c634fd97042713d69
Generic progress report system with optional stdout and wm.progress
output.
This works as a context manager: For any step in the process a loop can
be wrapped in the ProgressContext context manager. These classes are
generated by make_progress_reporter, so the main output options can be
defined on a high level, while actual number of steps is defined only
when actually running the job and the total amount of items is known.
===================================================================
M object_physics_meadow/hierarchical_dart_throw.py
M object_physics_meadow/meadow.py
M object_physics_meadow/patch.py
M object_physics_meadow/ui.py
M object_physics_meadow/util.py
===================================================================
diff --git a/object_physics_meadow/hierarchical_dart_throw.py b/object_physics_meadow/hierarchical_dart_throw.py
index 77b84f1..78f8ca7 100644
--- a/object_physics_meadow/hierarchical_dart_throw.py
+++ b/object_physics_meadow/hierarchical_dart_throw.py
@@ -51,6 +51,10 @@ class GridLevel():
self.cells.append(cell)
return cell
+ @staticmethod
+ def num_cells_in_range(imin, imax, jmin, jmax, kmin, kmax):
+ return (imax - imin) * (jmax - jmin) * (kmax - kmin)
+
def set_active_cells(self, imin, imax, jmin, jmax, kmin, kmax):
tot = (imax - imin) * (jmax - jmin) * (kmax - kmin)
self.cells = [None] * tot
@@ -58,6 +62,7 @@ class GridLevel():
for k in range(kmin, kmax):
for j in range(jmin, jmax):
for i in range(imin, imax):
+ progress_add(1)
self.cells[c] = GridCell(i, j, k)
c += 1
@@ -119,7 +124,17 @@ class PointCell():
self.points = []
class PointGrid():
- def __init__(self, radius, b0, gridmin, gridmax):
+ @staticmethod
+ def num_cells(radius, gridmin, gridmax):
+ size = radius
+ amin = ifloor(gridmin[0] / size) - 1
+ bmin = ifloor(gridmin[1] / size) - 1
+ na = ifloor(gridmax[0] / size) + 2 - amin
+ nb = ifloor(gridmax[1] / size) + 2 - bmin
+
+ return na * nb
+
+ def __init__(self, radius, gridmin, gridmax):
width = gridmax[0] - gridmin[0]
height = gridmax[1] - gridmin[1]
size = radius
@@ -132,8 +147,13 @@ class PointGrid():
self.na = ifloor(gridmax[0] / size) + 2 - self.amin
self.nb = ifloor(gridmax[1] / size) + 2 - self.bmin
+ # modified range generator for progress reports
+ def range_progress(tot):
+ for i in range(tot):
+ progress_add(1)
+ yield i
# note: row-major, so we can address it with cells[i][j]
- self.cells = tuple(tuple(PointCell() for j in range(self.nb)) for i in range(self.na))
+ self.cells = tuple(tuple(PointCell() for j in range_progress(self.nb)) for i in range(self.na))
def grid_from_loc(self, point):
s = self.invsize
@@ -216,7 +236,8 @@ def split_cell(radius2, b0, pgrid, child_level, cell, x0, x1, y0, y1, z0, z1):
if not is_covered(radius2, b0, pgrid, child_level, ci, cj, cx0, cx1, cy0, cy1):
child_cell = child_level.activate(ci, cj, ck)
-def hierarchical_dart_throw_gen(radius, max_levels, xmin, xmax, ymin, ymax):
+def hierarchical_dart_throw_gen(radius, max_levels, xmin, xmax, ymin, ymax,
+ progress_reporter=DummyProgressContext):
radius2 = radius * radius
gridmin = (xmin, ymin)
gridmax = (xmax, ymax)
@@ -232,28 +253,33 @@ def hierarchical_dart_throw_gen(radius, max_levels, xmin, xmax, ymin, ymax):
levels = [base_level] + [GridLevel(i, base_level.size / (2**i), radius) for i in range(1, max_levels)]
epsilon = levels[-1].weight * 0.5
- base_level.set_active_cells(imin, imax, jmin, jmax, 0, 1)
+ with progress_reporter("Activate Cells", 0, GridLevel.num_cells_in_range(imin, imax, jmin, jmax, 0, 1)):
+ base_level.set_active_cells(imin, imax, jmin, jmax, 0, 1)
- pgrid = PointGrid(radius, b0, gridmin, gridmax)
+ with progress_reporter("Init Spatial Grid", 0, PointGrid.num_cells(radius, gridmin, gridmax)):
+ pgrid = PointGrid(radius, gridmin, gridmax)
- for i in range(num):
- if not any(level.cells for level in levels):
- break
-
- level, cell = pop_cell(levels)
- if level:
- x0, x1, y0, y1, z0, z1 = level.cell_corners(cell)
+ with progress_reporter("Generate Samples", 0, num):
+ for i in range(num):
+ progress_add(1)
- # test coverage
- if not is_covered(radius2, b0, pgrid, level, cell.i, cell.j, x0, x1, y0, y1):
- point = level.sample(x0, x1, y0, y1, z0, z1)
- if test_disk(radius2, pgrid, point, level, cell.i, cell.j):
- yield point
- pgrid.insert(point)
- else:
- if level.index < max_levels - 1:
- split_cell(radius2, b0, pgrid, levels[level.index+1], cell, x0, x1, y0, y1, z0, z1)
- else:
- break
-
+ if not any(level.cells for level in levels):
+ break
+
+ level, cell = pop_cell(levels)
+ if level:
+ x0, x1, y0, y1, z0, z1 = level.cell_corners(cell)
+
+ # test coverage
+ if not is_covered(radius2, b0, pgrid, level, cell.i, cell.j, x0, x1, y0, y1):
+ point = level.sample(x0, x1, y0, y1, z0, z1)
+ if test_disk(radius2, pgrid, point, level, cell.i, cell.j):
+ yield point
+ pgrid.insert(point)
+ else:
+ if level.index < max_levels - 1:
+ split_cell(radius2, b0, pgrid, levels[level.index+1], cell, x0, x1, y0, y1, z0, z1)
+ else:
+ break
+
return gen
diff --git a/object_physics_meadow/meadow.py b/object_physics_meadow/meadow.py
index e5013d7..6642ea9 100644
--- a/object_physics_meadow/meadow.py
+++ b/object_physics_meadow/meadow.py
@@ -26,6 +26,7 @@ from object_physics_meadow import patch, blob
from object_physics_meadow.duplimesh import project_on_ground
#from object_physics_meadow import dupliparticle
#from object_physics_meadow.pointcache import cache_filename
+from object_physics_meadow.util import *
from object_physics_meadow.best_candidate import best_candidate_gen
from object_physics_meadow.hierarchical_dart_throw import hierarchical_dart_throw_gen
@@ -44,7 +45,7 @@ def make_samples(context, gridob, groundob):
# get a sample generator implementation
#gen = best_candidate_gen(groundob.meadow.patch_radius, xmin, xmax, ymin, ymax)
- gen = hierarchical_dart_throw_gen(groundob.meadow.patch_radius, groundob.meadow.sampling_levels, xmin, xmax, ymin, ymax)
+ gen = hierarchical_dart_throw_gen(groundob.meadow.patch_radius, groundob.meadow.sampling_levels, xmin, xmax, ymin, ymax, progress_reporter=make_progress_reporter(True, True))
mat = groundob.matrix_world
loc2D = [(mat * Vector(p[0:3] + (1.0,)))[0:2] for p in gen(groundob.meadow.seed, groundob.meadow.max_patches)]
@@ -59,17 +60,17 @@ def make_blobs(context, gridob, groundob):
if use_profiling:
prof = cProfile.Profile()
prof.enable()
- samples2D = make_samples(context, gridob, groundob)
- blob.make_blobs(context, gridob, groundob, samples2D, groundob.meadow.patch_radius)
+
+ samples2D = make_samples(context, gridob, groundob)
+ blob.make_blobs(context, gridob, groundob, samples2D, groundob.meadow.patch_radius)
+
+ if use_profiling:
prof.disable()
s = io.StringIO()
ps = pstats.Stats(prof, stream=s).sort_stats('tottime')
ps.print_stats()
print(s.getvalue())
- else:
- samples2D = make_samples(context, gridob, groundob)
- blob.make_blobs(context, gridob, groundob, samples2D, groundob.meadow.patch_radius)
### Patch copies for simulation ###
def make_patches(context, gridob, groundob):
diff --git a/object_physics_meadow/patch.py b/object_physics_meadow/patch.py
index eae3b71..888c70d 100644
--- a/object_physics_meadow/patch.py
+++ b/object_physics_meadow/patch.py
@@ -236,52 +236,53 @@ def bake_psys(context, ob, psys):
# restore
ob.particle_systems.active = curpsys
-def bake_all(context):
+def count_bakeable(context):
+ num = 0
+ for ob in patch_objects(context):
+ for psys in ob.particle_systems:
+ num += 1
+ return num
+
+def bake_all(context, progress_reporter):
settings = _settings.get(context)
wm = context.window_manager
total_time = 0.0
avg_time = 0.0
- # XXX Note: wm.progress updates are disabled for now, because the bake
- # operator overrides this with it's own progress numbers ...
-
total = count_bakeable(context)
- #wm.progress_begin(0, total)
-
- num = 0
- for ob in patch_objects(context):
- for psys in ob.particle_systems:
- sys.stdout.write("Baking blob {}/{} ... ".format(str(num).rjust(5), str(total).ljust(5)))
- sys.stdout.flush()
-
- start_time = time.time()
-
- bake_psys(context, ob, psys)
-
- duration = time.time() - start_time
- total_time += duration
- avg_time = total_time / float(num + 1)
-
- #wm.progress_update(num)
- time_string = lambda x: time.strftime("%H:%M:%S", time.gmtime(x)) + ".%02d" % (int(x * 100.0) % 100)
- durstr = time_string(duration)
- avgstr = time_string(avg_time) if avg_time > 0.0 else "--:--:--"
- etastr = time_string(avg_time * (total - num)) if avg_time > 0.0 else "--:--:--"
- sys.stdout.write("{} (avg. {}, ETA {})\n".format(durstr, avgstr, etastr))
- sys.stdout.flush()
- num += 1
- #wm.progress_end()
-
-def count_bakeable(context):
- num = 0
- for ob in patch_objects(context):
- for psys in ob.particle_systems:
- num += 1
- return num
+ with progress_reporter("Bake Blob", 0, total):
+ """
+ num = 0
+ """
+ for ob in patch_objects(context):
+ for psys in ob.particle_systems:
+ """
+ sys.stdout.write("Baking blob {}/{} ... ".format(str(num).rjust(5), str(total).ljust(5)))
+ sys.stdout.flush()
+
+ start_time = time.time()
+ """
+
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-extensions-cvs
mailing list