From 8e5a1467854c8bad9584ae5e2ae6a90623daffcf Mon Sep 17 00:00:00 2001 From: Wenzel Jakob Date: Tue, 4 Feb 2014 21:05:13 +0100 Subject: [PATCH] fix a Python<->Mitsuba<->Qt issue reported by Marios Papas --- doc/python.tex | 20 +++++++++++++------- include/mitsuba/render/renderjob.h | 3 +++ src/libpython/base.h | 2 ++ src/libpython/render.cpp | 5 +++-- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/doc/python.tex b/doc/python.tex index d5abec72..8ba43f87 100644 --- a/doc/python.tex +++ b/doc/python.tex @@ -585,6 +585,7 @@ class MitsubaRenderBuffer(RenderListener): RENDERING_FINISHED = 0 RENDERING_CANCELLED = 1 RENDERING_UPDATED = 2 + GEOMETRY_CHANGED = 3 def __init__(self, queue, callback): super(MitsubaRenderBuffer, self).__init__() @@ -613,7 +614,7 @@ class MitsubaRenderBuffer(RenderListener): do this occasionally). Hence, tonemap the full film. """ film = self._get_film_ensure_initialized(job) film.develop(Point2i(0), self.size, Point2i(0), self.bitmap) - self._potentially_send_update(force=True) + self._potentially_send_update() def finishJobEvent(self, job, cancelled): """ Callback: the rendering job has finished or was cancelled. @@ -646,12 +647,14 @@ class MitsubaRenderBuffer(RenderListener): # (i.e. without doing unnecessary bitmap copy operations) self.qimage = QImage(self.bitmap.getNativeBuffer(), self.size.x, self.size.y, QImage.Format_RGB888) + + self.callback(MitsubaRenderBuffer.GEOMETRY_CHANGED) return film - def _potentially_send_update(self, force = False): + def _potentially_send_update(self): """ Send an update request to any attached widgets, but not too often """ now = time.time() - if now - self.time > .25 or force: + if now - self.time > .25: self.time = now self.callback(MitsubaRenderBuffer.RENDERING_UPDATED) @@ -660,20 +663,22 @@ class RenderWidget(QWidget): and displays the progress of everything that's being rendered """ renderingUpdated = Signal(int) - def __init__(self, parent, queue): + def __init__(self, parent, queue, default_size = Vector2i(0, 0)): QWidget.__init__(self, parent) self.buffer = MitsubaRenderBuffer(queue, self.renderingUpdated.emit) # Need a queued conn. to avoid threading issues between Qt and Mitsuba self.renderingUpdated.connect(self._handle_update, Qt.QueuedConnection) self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) + self.default_size = default_size def sizeHint(self): - return QSize(self.buffer.size.x, self.buffer.size.y) + size = self.buffer.size if not self.buffer.size.isZero() else self.default_size + return QSize(size.x, size.y) def _handle_update(self, event): image = self.buffer.qimage # Detect when an image of different resolution is being rendered - if image.width() < self.width() or image.height() < self.height(): + if image.width() > self.width() or image.height() > self.height(): self.updateGeometry() self.repaint() @@ -702,10 +707,11 @@ class MitsubaDemo(QMainWindow): # Initialize Mitsuba self.initializeMitsuba() self.job = self.createRenderJob() + self.job.setInteractive(True) # Initialize the user interface status = self.statusBar() - self.rwidget = RenderWidget(self, self.queue) + self.rwidget = RenderWidget(self, self.queue, self.scene.getFilm().getSize()) progress = QProgressBar(status) status.setContentsMargins(0,0,5,0) status.addPermanentWidget(progress) diff --git a/include/mitsuba/render/renderjob.h b/include/mitsuba/render/renderjob.h index 85eff44e..b48234bc 100644 --- a/include/mitsuba/render/renderjob.h +++ b/include/mitsuba/render/renderjob.h @@ -92,6 +92,9 @@ public: */ inline bool isInteractive() const { return m_interactive; } + /// Define whether or not this is an interactive job + inline void setInteractive(bool interactive) { m_interactive = interactive; } + /// Get a pointer to the underlying scene inline Scene *getScene() { return m_scene.get(); } diff --git a/src/libpython/base.h b/src/libpython/base.h index 5f62335b..5e546a4d 100644 --- a/src/libpython/base.h +++ b/src/libpython/base.h @@ -70,6 +70,7 @@ .def(bp::self / Scalar()) \ .def(bp::self /= Scalar()) \ .def("serialize", &Name::serialize) \ + .def("isZero", &Name::isZero) \ .def("length", &Name::length) \ .def("lengthSquared", &Name::lengthSquared) \ .def("__repr__", &Name::toString) \ @@ -95,6 +96,7 @@ .def(bp::self / Scalar()) \ .def(bp::self /= Scalar()) \ .def("serialize", &Name::serialize) \ + .def("isZero", &Name::isZero) \ .def("__repr__", &Name::toString) \ .def("__len__", &FixedSizeSupport::len) \ .def("__getitem__", &FixedSizeSupport::get) \ diff --git a/src/libpython/render.cpp b/src/libpython/render.cpp index f598d0d9..8ef389bf 100644 --- a/src/libpython/render.cpp +++ b/src/libpython/render.cpp @@ -363,11 +363,12 @@ void export_render() { Scene *(RenderJob::*renderJob_getScene)(void) = &RenderJob::getScene; RenderQueue *(RenderJob::*renderJob_getRenderQueue)(void) = &RenderJob::getRenderQueue; - BP_CLASS(RenderJob, Thread, (bp::init())) - .def(bp::init >()) + BP_CLASS(RenderJob, Thread, (bp::init >())) .def("flush", &RenderJob::flush) .def("cancel", renderJob_cancel) .def("wait", &RenderJob::wait) + .def("isInteractive", &RenderJob::isInteractive) + .def("setInteractive", &RenderJob::setInteractive) .def("getScene", renderJob_getScene, BP_RETURN_VALUE) .def("getRenderQueue", renderJob_getRenderQueue, BP_RETURN_VALUE);