3-D visualizer¶
gutenberg_kg.viz3d
¶
viz3d.py — 3-D Knowledge Tree Forest visualiser for GutenbergKG.
Each book is rendered as a tree: - Trunk → document node (brown cylinder, height ∝ log(chunk_count)) - Branches → section nodes (forest-green spheres radiating from trunk apex) - Leaves → chunk nodes (light-green spheres clustered around each section) - Spores → entity / topic nodes (gold dots floating above the canopy)
Books are grouped by genre into groves, with genres arranged in a large Fibonacci annulus so the whole corpus forms a navigable 3-D forest.
This module is the Qt viewer only: corpus scanning, layout, and scene
composition live in :mod:gutenberg_kg.scene, which knows nothing about Qt so
the off-screen light-field renderer (gutenkg quilt) can share them.
Requires: pyvista, pyvistaqt, PyQt5, param, numpy, and the shared 3-D layout
primitives from kg_utils.viz3d (kgmodule-utils' viz3d extra).
Author: Eric G. Suchanek, PhD
ForestMainWindow(corpus_root=DEFAULT_CORPUS, save_path=DEFAULT_SAVE, width=1500, height=950)
¶
Bases: QMainWindow
Qt main window for the Gutenberg 3-D forest visualiser.
Left panel — corpus path, genre selector, book selector, render options. Right panel — PyVista QtInteractor + button row.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
corpus_root
|
str
|
Path to the corpus directory. |
DEFAULT_CORPUS
|
save_path
|
str
|
Default output file stem for exports. |
DEFAULT_SAVE
|
width
|
int
|
Initial window width in pixels. |
1500
|
height
|
int
|
Initial window height in pixels. |
950
|
Build the main window: control/viewport panels, mesh picking, and signal wiring.
Source code in src/gutenberg_kg/viz3d.py
580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 | |
cast_povray()
¶
Ray-trace a full light-field quilt and push it to the Looking Glass.
The same scene the preview traced, at the Looking Glass preset instead
of a single view — so this is :data:POV_PREVIEW_SIZE arithmetic times
n_views, which is minutes rather than seconds. The quilt is
written to renders/pov/ before Bridge is contacted, so a failed
cast still leaves the hologram file behind.
Source code in src/gutenberg_kg/viz3d.py
1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 | |
cast_to_looking_glass()
¶
Render the current view as a quilt and push it to the Looking Glass.
Re-composes the same scene into an off-screen plotter and copies this window's camera, so what is cast is the view being looked at — then hands the quilt to Bridge. Needs Looking Glass Bridge running on this machine; the render is kept either way.
The quilt is rendered at :data:CAST_SCALE of the preset's pixel size:
the local render costs about a second at full size, but the wait is
Bridge loading the resulting PNG, and that scales with its area.
Source code in src/gutenberg_kg/viz3d.py
1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 | |
cleanup()
¶
Close any open popup, stop a running trace, and tear down the plotter.
Order matters: the render session goes first. A QThread still
running when the window is destroyed aborts the process, and a queued
signal delivered after these widgets are gone raises from inside Qt —
so the session is detached before anything it touches is torn down.
Source code in src/gutenberg_kg/viz3d.py
1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 | |
closeEvent(event)
¶
Qt window-close handler: run :meth:cleanup (warnings suppressed) then accept.
Source code in src/gutenberg_kg/viz3d.py
1507 1508 1509 1510 1511 1512 1513 1514 1515 | |
frame_for_render()
¶
Put the viewport camera exactly where the renderers will put theirs.
Reset View frames whatever actors are on screen, ground slab and
all. This frames the subject: :func:kg_utils.viz3d.frame_tree is
the one rule gutenkg pov and gutenkg quilt also use, so after
pressing this the viewport is a true preview of the render — which is
what makes the depth budget on a light-field panel predictable rather
than a matter of nudging the mouse.
Falls back to the plotter's bounds when no tree has been grown yet,
the same fallback :func:tree_pov_camera makes.
Source code in src/gutenberg_kg/viz3d.py
1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 | |
on_pick(actor)
¶
Right-click callback: find nearest node and show text popup.
Source code in src/gutenberg_kg/viz3d.py
1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 | |
on_render_clicked()
¶
Render button handler: drive whichever backend the style names.
Source code in src/gutenberg_kg/viz3d.py
1038 1039 1040 1041 1042 1043 | |
on_status_change(event)
¶
param watcher for visualizer.status: re-emit as the Qt status_changed signal.
Source code in src/gutenberg_kg/viz3d.py
1442 1443 1444 1445 | |
render_povray()
¶
Ray-trace the loaded book and show the result.
Loads if needed, writes the .pov beside the other renders, then
hands the trace to :class:PovRenderWorker so the window stays
responsive. The camera comes from the viewport, so what is traced is
what is being looked at — use Frame for Render first to put the
viewport where the quilt would be.
Source code in src/gutenberg_kg/viz3d.py
1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 | |
reset_camera()
¶
Reset the plotter camera to the default isometric view and zoom level.
Source code in src/gutenberg_kg/viz3d.py
1393 1394 1395 1396 1397 1398 1399 1400 | |
reset_settings()
¶
Reset Settings button handler: clear selections, restore default visibility checkboxes, and reset the camera.
Source code in src/gutenberg_kg/viz3d.py
1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 | |
save_current_view()
¶
Save View button handler: export the current scene to HTML or a screenshot.
Source code in src/gutenberg_kg/viz3d.py
1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 | |
show_selected_text()
¶
Show text for the first selected book in the book selector.
Source code in src/gutenberg_kg/viz3d.py
1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 | |
update_status_display(status)
¶
Render status into the status label, color-coded by message type (error/busy/done).
Source code in src/gutenberg_kg/viz3d.py
1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 | |
update_window_title(event)
¶
param watcher for visualizer.window_title: apply it to the Qt window.
Source code in src/gutenberg_kg/viz3d.py
1459 1460 1461 | |
GutenbergForestVisualizer(plotter=None, **params)
¶
Bases: Parameterized
Data and state model for the Gutenberg 3-D forest visualiser.
Reactive attributes (via param) drive the Qt control panel.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
corpus_root
|
Path to the corpus directory. |
required | |
plotter
|
Plotter | None
|
The |
None
|
Initialise the visualiser data model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plotter
|
Plotter | None
|
The |
None
|
params
|
Additional |
{}
|
Source code in src/gutenberg_kg/viz3d.py
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 | |
load_selected()
¶
Load nodes and edges for the currently selected genres/books.
Populates :attr:all_nodes, :attr:all_edges, :attr:_book_genre_map.
Source code in src/gutenberg_kg/viz3d.py
505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 | |
visualize()
¶
Load selected books and render the 3-D forest.
Source code in src/gutenberg_kg/viz3d.py
542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 | |
TextPopup(title, text, parent=None, on_close_callback=None)
¶
Bases: QDialog
Modeless popup that renders node text as Markdown HTML.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title
|
str
|
Window title. |
required |
text
|
str
|
Raw text content. |
required |
parent
|
Parent widget. |
None
|
|
on_close_callback
|
Called when the window closes. |
None
|
Build the popup dialog: title bar, rendered Markdown browser, and Close button.
Source code in src/gutenberg_kg/viz3d.py
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 | |
closeEvent(event)
¶
Invoke the close callback, if any, then let the dialog close normally.
Source code in src/gutenberg_kg/viz3d.py
308 309 310 311 312 | |
create_forest_visualization(viz, plotter)
¶
Render the knowledge tree forest into plotter for the Qt viewer.
Thin wrapper over :func:gutenberg_kg.scene.build_forest_scene: it maps
the visualiser's param toggles onto :class:~gutenberg_kg.scene.SceneFilters
and pumps the Qt event loop from the builder's progress callback so the
status bar stays live during a long build.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
viz
|
GutenbergForestVisualizer
|
:class: |
required |
plotter
|
Plotter
|
The |
required |
Returns:
| Type | Description |
|---|---|
tuple[Plotter, str, dict[str, dict]]
|
|
Source code in src/gutenberg_kg/viz3d.py
320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 | |
launch(corpus_root=DEFAULT_CORPUS, width=1500, height=950, **_kwargs)
¶
Open the Gutenberg KG Forest window and run the Qt event loop.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
corpus_root
|
str
|
Path to the corpus directory ( |
DEFAULT_CORPUS
|
width
|
int
|
Initial window width in pixels. |
1500
|
height
|
int
|
Initial window height in pixels. |
950
|
Source code in src/gutenberg_kg/viz3d.py
1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 | |