# [Bf-extensions-cvs] [a996e50] master: Simplified progress reports: Use simple module-level settings for controlling output, and don't pass report types as extra args.

Tue Dec 16 10:24:15 CET 2014

```Commit: a996e50204231290d8871ce96ecfe9904fc5da45
Author: Lukas Tönne
Date:   Tue Dec 16 10:21:56 2014 +0100
Branches: master
https://developer.blender.org/rBACa996e50204231290d8871ce96ecfe9904fc5da45

Simplified progress reports: Use simple module-level settings for
controlling output, and don't pass report types as extra args.

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

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

index 78f8ca7..b395896 100644
@@ -23,6 +23,7 @@ import bpy
from math import *

# Implements Poisson Disk sampling according to
# "Poisson Disk Point Sets by Hierarchical Dart Throwing"
@@ -62,7 +63,7 @@ class GridLevel():
for k in range(kmin, kmax):
for j in range(jmin, jmax):
for i in range(imin, imax):
self.cells[c] = GridCell(i, j, k)
c += 1

@@ -150,7 +151,7 @@ class PointGrid():
# modified range generator for progress reports
def range_progress(tot):
for i in range(tot):
yield i
# note: row-major, so we can address it with cells[i][j]
self.cells = tuple(tuple(PointCell() for j in range_progress(self.nb)) for i in range(self.na))
@@ -236,8 +237,7 @@ 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,
-                                progress_reporter=DummyProgressContext):
+def hierarchical_dart_throw_gen(radius, max_levels, xmin, xmax, ymin, ymax):
gridmin = (xmin, ymin)
gridmax = (xmax, ymax)
@@ -253,15 +253,15 @@ 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

-        with progress_reporter("Activate Cells", 0, GridLevel.num_cells_in_range(imin, imax, jmin, jmax, 0, 1)):
+        with progress.ProgressContext("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)

-        with progress_reporter("Init Spatial Grid", 0, PointGrid.num_cells(radius, gridmin, gridmax)):
+        with progress.ProgressContext("Init Spatial Grid", 0, PointGrid.num_cells(radius, gridmin, gridmax)):

-        with progress_reporter("Generate Samples", 0, num):
+        with progress.ProgressContext("Generate Samples", 0, num):
for i in range(num):

if not any(level.cells for level in levels):
break
index 0e10bec..e3f2768 100644
@@ -45,7 +45,7 @@ def make_samples(context, gridob, groundob):

# get a sample generator implementation

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)]
index 1270a18..aa48565 100644
@@ -24,6 +24,7 @@ from bpy_extras import object_utils

from object_physics_meadow import settings as _settings

#-----------------------------------------------------------------------

@@ -243,7 +244,7 @@ def count_bakeable(context):
num += 1
return num

-def bake_all(context, progress_reporter):
+def bake_all(context):
settings = _settings.get(context)
wm = context.window_manager

@@ -252,13 +253,13 @@ def bake_all(context, progress_reporter):

total = count_bakeable(context)

-    with progress_reporter("Bake Blob", 0, total):
+    with progress.ProgressContext("Bake Blob", 0, total):
for ob in patch_objects(context):
for psys in ob.particle_systems:
bake_psys(context, ob, psys)

-def patch_objects_rebake(context, progress_reporter=DummyProgressContext):
+def patch_objects_rebake(context):
settings = _settings.get(context)
wm = context.window_manager

@@ -270,6 +271,6 @@ def patch_objects_rebake(context, progress_reporter=DummyProgressContext):
# XXX have to set this because bake operator only bakes up to the last frame ...
scene.frame_current = scene.frame_end

-        bake_all(context, progress_reporter)
+        bake_all(context)

scene.frame_set(curframe)
new file mode 100644
index 0000000..16c5431
--- /dev/null
@@ -0,0 +1,134 @@
+### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+import bpy, time, sys
+from math import *
+
+show_progress_bar = True
+show_stdout = False
+
+_progress_context = None
+
+def _get_time_string(x):
+    if x >= 0.0:
+        return time.strftime("%H:%M:%S", time.gmtime(x)) + ".%02d" % (int(x * 100.0) % 100)
+    else:
+        return "??:??:??.??"
+
+class ProgressContext():
+    def __init__(self, name, pmin, pmax):
+        self.name = name
+        self.pmin = pmin
+        self.pmax = pmax
+        self.tot = pmax - pmin
+        self.norm = 1.0 / float(self.tot) if self.tot > 0 else 0.0
+
+        self.pcur = pmin
+        self.perc_show = -2.0 # last displayed percentage, init to make sure we show the first time
+
+        self.duration = 0.0
+        self.start_time = 0.0
+
+    def __enter__(self):
+        global _progress_context, show_progress_bar, show_stdout
+
+        assert(_progress_context is None)
+        _progress_context = self
+
+        self.start_time = time.time()
+
+        if show_progress_bar:
+            wm = bpy.context.window_manager
+            # always use 0..100 percentage on the progress counter,
+            # it does not display large numbers well
+            wm.progress_begin(0, 100)
+
+    def __exit__(self, exc_type, exc_value, traceback):
+        global _progress_context, show_progress_bar, show_stdout
+
+        if show_progress_bar:
+            wm = bpy.context.window_manager
+            wm.progress_end()
+
+        if show_stdout:
+            # make a final report
+            done = self.pcur - self.pmin
+            sys.stdout.write("\r>> {}: {}/{}, {}".format(self.name,
+                                                                str(done).rjust(len(str(self.tot))), str(self.tot),
+                                                                _get_time_string(self.duration)))
+            # clean newline
+            sys.stdout.write("\n")
+            sys.stdout.flush()
+
+        assert(_progress_context is self)
+        _progress_context = None
+
+    def estimate_total_duration(self):
+        done = self.pcur - self.pmin
+        if done > 0:
+            return self.duration * self.tot / done
+        else:
+            return -1.0
+
+    def set_progress(self, value, message):
+        global _progress_context, show_progress_bar, show_stdout
+
+        self.pcur = value
+        done = value - self.pmin
+        perc = 100.0 * done * self.norm
+
+        # only write to progress indicator or stdout if the percentage actually changed
+        if perc > self.perc_show + 1.0:
+            self.perc_show = perc
+            perc = min(max(perc, 0), 100)
+
+            self.duration = time.time() - self.start_time
+
+            if show_progress_bar:
+                wm = bpy.context.window_manager
+                wm.progress_update(perc)
+
+            if show_stdout:
+                bar = 50
+                filled = int(bar * done * self.norm)
+
+                eta = self.estimate_total_duration()
+
+                sys.stdout.write("\r>> {}: {}/{} [{}{}] {}/{} | {}".format(self.name,
+                                                                           str(done).rjust(len(str(self.tot))), str(self.tot),
+                                                                           '.' * filled, ' ' * (bar - filled),
+                                                                           _get_time_string(self.duration), _get_time_string(eta),
+                                                                           message))
+                sys.stdout.flush()
+
+def progress_set(value, mess

@@ Diff output truncated at 10240 characters. @@

```