CHANGELOG
All notable changes between the original voxmapper.py (tkinter) and the current voxmapper_qt.py (PyQt6) implementation.
This changelog summarizes refactors, new features, bug fixes, and behavioral differences introduced when the project was migrated and modernized.
v1.4.2 (migration -> PyQt6 & improvements)
Major refactor
- Rewrote UI from
tkinter(voxmapper.py) toPyQt6(voxmapper_qt.py). The application now uses aMainWindowclass and modular UI builders inui_builder.py. - UI construction split into separate builders:
build_noise_ui,build_grass_ui,build_landmass_ui,build_image_ui. - Theme handling extracted to a
ThemeManager(theme_worker.py) and applied at startup. - Worker logic moved into dedicated worker threads in
preview_workers.py(e.g.,NoiseWorker,GrassWorker,LandmassWorker,ImageWorker,GenerateHeightmapWorker,GrassExportWorker). This replaces older inline threading/multiprocessing usage. - Executor/manager pattern introduced (
executor_manager.py) to handle multiprocessing pools for chunked noise generation.
User interface and UX
- Consistent modern Qt UI with tabbed interface:
Noise,Landmass,Grass Map,Image Import. - Preview canvases implemented with
QLabelwidgets showing scaledQPixmap/QImagefrom PIL conversions. - Interactive preview pan and zoom implemented using
eventFilteron preview labels (mouse drag + wheel zoom) while preserving focus mapping between preview and export. - Zoom and position indicators added to UI (
zoom_label,position_label) and updated during interactions. - Sliders linked to spinboxes with helper
_link_slider_to_spinboxfor consistent UX.
Progress and export improvements
- Export operations (heightmap/generations) now provide visible progress bars and cancel buttons:
- Noise heightmap export uses
export_progress(universal) above the Noise preview. - Grass export has
grass_export_progressabove the Grass preview and aGrassExportWorkerthat emits progress updates per-row. - Landmass export now has
land_export_progressabove the Landmass preview and usesGenerateHeightmapWorkerprogress updates for multiprocess stages.
- Noise heightmap export uses
- Cancel button wired to request thread interruption (
requestInterruption) and sets shared flags where applicable. - Export cleanup consolidated in
_export_finished_cleanupwhich hides and resets all progress bars and disconnects worker signals.
Worker & generation changes
- Noise generation moved into chunked multiprocessing via
executor_managerand worker helpers; results are stitched together (np.vstack) and post-processed throughcreate_heightmap. GenerateHeightmapWorkerreports progress across multiple stages (noise generation, postprocessing, saving) viaprogresssignal.GrassExportWorkeradded and implemented to emitprogressand support cancellation; exports grass maps directly from a worker thread.start_noise_workerhelper returns a startedNoiseWorkerand adds acancelconvenience method.
Image & import handling
- Image import and processing use PIL with safe
pil_to_qimagehelper producing deep-copiedQImageto avoid use-after-free crashes. - Image preview updates run in
ImageWorkerthread to keep UI responsive. - Grayscale conversion, green overlay, gaussian blur, and other filters handled more robustly (PIL
ImageFilter, numpy operations).
Robustness and reliability
- Added a Qt-friendly top-level exception hook
qt_exception_hookto show errors in message boxes while printing stack traces to console. - Extensive try/except usage to avoid crashing the GUI from worker exceptions.
- Logging improved through Python
loggingcalls for debug and error visibility. - Graceful worker interruption attempts: workers are requested to stop and waited for briefly before forced termination.
Bugs fixed / behavioral changes
- Fixed landmass export cleanup bug (incorrect
self._export.finished_cleanupreference) -> now connects to_export_finished_cleanup. - Progress bars for Grass and Landmass exports added (user-visible progress previously absent for grass exports).
- Preview-scaling mapping: preview zoom/scale accounting improved so exports match the preview view (store
_last_preview_effective_scaleand use to compute exportscale). - Safe QImage conversion to avoid GUI crashes when worker threads exit (deep copy strategy in
pil_to_qimage).
Removed or changed features
tkinterUI removed entirely; legacyvoxmapper.pyfunctions andtkwidgets replaced by PyQt equivalents.- Some tightly-coupled inline functions in the old monolith split into smaller modules (e.g.,
ui_builder.py,preview_workers.py,executor_manager.py,workers_utils.py).
Developer-facing changes
- Project structure changed — new modules to review:
ui_builder.py,preview_workers.py,executor_manager.py,theme_worker.py,workers_utils.py. - README version bumped to
v1.4.2and short notes added.