Skip to content

Commit adcdbf7

Browse files
committed
updating GUI for reliable connections and parameters
1 parent 0655da9 commit adcdbf7

File tree

11 files changed

+5949
-405
lines changed

11 files changed

+5949
-405
lines changed

docs/api/domain.html

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ <h4 class="sidebar-title">Contents</h4>
9999
<li><a href="#constructor"><i class="fas fa-hammer"></i> Constructor</a></li>
100100
<li><a href="#attributes"><i class="fas fa-database"></i> Attributes</a></li>
101101
<li><a href="#methods"><i class="fas fa-cogs"></i> Methods</a></li>
102+
<li><a href="#persistence"><i class="fas fa-save"></i> Persistence</a></li>
102103
<li><a href="#operators"><i class="fas fa-calculator"></i> Operators</a></li>
103104
<li><a href="#examples"><i class="fas fa-code"></i> Examples</a></li>
104105
<li><a href="#notes"><i class="fas fa-info-circle"></i> Notes</a></li>
@@ -440,6 +441,87 @@ <h3>Utility Methods</h3>
440441
</div>
441442
</section>
442443

444+
<!-- Persistence Section -->
445+
<section id="persistence" class="api-section">
446+
<h2>Persistence (Save/Load)</h2>
447+
448+
<p>Domains can be saved to and loaded from <code>.dmn</code> files, allowing you to preserve
449+
expensive implicit function computations and share domain configurations.</p>
450+
451+
<div class="api-method">
452+
<div class="api-method-signature">
453+
<code>save(path, include_boundary=False, include_mesh=False, include_patch_normals=True)</code>
454+
</div>
455+
<p>Save the domain to a <code>.dmn</code> file.</p>
456+
<div class="api-method-params">
457+
<h4>Parameters</h4>
458+
<ul>
459+
<li><code>path</code> (str): Output filename. If no extension is provided, <code>.dmn</code> is appended.</li>
460+
<li><code>include_boundary</code> (bool): Persist the boundary mesh for visualization without recomputation. Default is False.</li>
461+
<li><code>include_mesh</code> (bool): Persist the interior mesh for sampling without recomputation. Default is False.</li>
462+
<li><code>include_patch_normals</code> (bool): Include per-patch normals to fully restore Patch objects. Default is True.</li>
463+
</ul>
464+
<h4>Notes</h4>
465+
<p>The saved file contains the implicit function coefficients and patch data needed to
466+
reconstruct the domain. Including boundary and mesh data increases file size but
467+
speeds up subsequent operations.</p>
468+
</div>
469+
</div>
470+
471+
<div class="api-method">
472+
<div class="api-method-signature">
473+
<code>Domain.load(path)</code> <span class="api-badge">classmethod</span>
474+
</div>
475+
<p>Load a domain from a <code>.dmn</code> file.</p>
476+
<div class="api-method-params">
477+
<h4>Parameters</h4>
478+
<ul>
479+
<li><code>path</code> (str): Path to a <code>.dmn</code> file.</li>
480+
</ul>
481+
<h4>Returns</h4>
482+
<ul>
483+
<li><code>Domain</code>: Fully initialized Domain instance ready for fast evaluation.</li>
484+
</ul>
485+
<h4>Notes</h4>
486+
<p>The loaded domain has its <code>function_tree</code> rebuilt and is ready for use
487+
with <code>__call__</code> (fast evaluation). Patches are reconstructed from stored
488+
arrays, enabling you to call <code>build()</code> again if needed.</p>
489+
</div>
490+
</div>
491+
492+
<div class="api-example">
493+
<h4>Save/Load Example</h4>
494+
<pre data-copy><code class="language-python">from svv.domain.domain import Domain
495+
import pyvista as pv
496+
497+
# Create domain from a complex mesh
498+
mesh = pv.read("heart_ventricle.stl")
499+
domain = Domain(mesh)
500+
domain.create() # Creates patches (can be slow for complex meshes)
501+
domain.solve() # Solves RBF system (expensive)
502+
domain.build() # Builds boundary and mesh
503+
504+
# Save domain for later use
505+
domain.save("ventricle.dmn", include_boundary=True, include_mesh=True)
506+
507+
# Later, load the domain instantly
508+
loaded_domain = Domain.load("ventricle.dmn")
509+
510+
# Use immediately - no need to call create/solve/build
511+
point = [[0.5, 0.5, 0.5]]
512+
inside = loaded_domain(point) < 0 # Fast evaluation works immediately
513+
514+
# Or call build() if you need fresh boundary/mesh
515+
loaded_domain.build()</code></pre>
516+
</div>
517+
518+
<div class="callout tip">
519+
<strong>Performance Tip:</strong> For complex domains, saving with <code>include_boundary=True</code>
520+
and <code>include_mesh=True</code> significantly speeds up subsequent loads at the cost of
521+
larger file sizes. This is especially useful when iterating on tree generation with the same domain.
522+
</div>
523+
</section>
524+
443525
<!-- Operators Section -->
444526
<section id="operators" class="api-section">
445527
<h2>Operators</h2>

docs/api/forest.html

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ <h4 class="sidebar-title">Contents</h4>
121121
<li><a href="#growth-methods"><i class="fas fa-seedling"></i> Growth Methods</a></li>
122122
<li><a href="#connection-methods"><i class="fas fa-link"></i> Connection Methods</a></li>
123123
<li><a href="#export-methods"><i class="fas fa-file-export"></i> Export Methods</a></li>
124+
<li><a href="#persistence"><i class="fas fa-save"></i> Persistence</a></li>
124125
<li><a href="#examples"><i class="fas fa-code"></i> Examples</a></li>
125126
<li><a href="#algorithms"><i class="fas fa-brain"></i> Algorithms</a></li>
126127
</ul>
@@ -388,6 +389,97 @@ <h4>Parameters</h4>
388389
</div>
389390
</section>
390391

392+
<!-- Persistence Section -->
393+
<section id="persistence" class="api-section">
394+
<h2>Persistence (Save/Load)</h2>
395+
396+
<p>Forests can be saved to and loaded from <code>.forest</code> files, enabling checkpointing during
397+
complex multi-tree growth processes and sharing of generated vascular networks.</p>
398+
399+
<div class="api-method">
400+
<div class="api-method-signature">
401+
<code>save(path, include_timing=False)</code>
402+
</div>
403+
<p>Save the forest to a <code>.forest</code> file.</p>
404+
<div class="api-method-params">
405+
<h4>Parameters</h4>
406+
<ul>
407+
<li><code>path</code> (str): Output filename. If no extension is provided, <code>.forest</code> is appended.</li>
408+
<li><code>include_timing</code> (bool): Include generation timing data for each tree. Default is False.</li>
409+
</ul>
410+
<h4>Returns</h4>
411+
<ul>
412+
<li><code>pathlib.Path</code>: Path to the saved file.</li>
413+
</ul>
414+
<h4>Notes</h4>
415+
<p>The saved file contains all forest data, tree parameters, and connectivity information.
416+
If <code>connect()</code> has been called, connections are also saved. <strong>The domain
417+
is NOT saved</strong> and must be set separately after loading via <code>set_domain()</code>.</p>
418+
</div>
419+
</div>
420+
421+
<div class="api-method">
422+
<div class="api-method-signature">
423+
<code>Forest.load(path)</code> <span class="api-badge">classmethod</span>
424+
</div>
425+
<p>Load a forest from a <code>.forest</code> file.</p>
426+
<div class="api-method-params">
427+
<h4>Parameters</h4>
428+
<ul>
429+
<li><code>path</code> (str): Path to a <code>.forest</code> file.</li>
430+
</ul>
431+
<h4>Returns</h4>
432+
<ul>
433+
<li><code>Forest</code>: Loaded forest instance with all trees and connections restored.</li>
434+
</ul>
435+
<h4>Notes</h4>
436+
<p>The loaded forest will NOT have a domain set. You must call <code>set_domain()</code>
437+
after loading to enable domain-dependent operations. If the forest was saved with
438+
connections (after calling <code>connect()</code>), those connections are restored.</p>
439+
</div>
440+
</div>
441+
442+
<div class="api-example">
443+
<h4>Save/Load Example</h4>
444+
<pre data-copy><code class="language-python">from svv.forest.forest import Forest
445+
from svv.domain.domain import Domain
446+
import pyvista as pv
447+
448+
# Create and grow a forest
449+
domain = Domain(pv.Cube())
450+
domain.create()
451+
domain.solve()
452+
domain.build()
453+
454+
forest = Forest()
455+
forest.set_domain(domain)
456+
forest.set_roots() # Uses default opposing start points
457+
forest.add(50)
458+
forest.connect()
459+
460+
# Save the complete forest (including connections)
461+
forest.save("vascular_network.forest")
462+
463+
# Later, load it back
464+
loaded_forest = Forest.load("vascular_network.forest")
465+
466+
# Re-attach the domain
467+
loaded_forest.set_domain(domain)
468+
469+
# Connections are preserved - can visualize immediately
470+
loaded_forest.show(plot_domain=True)
471+
472+
# Or continue growing
473+
loaded_forest.add(25)</code></pre>
474+
</div>
475+
476+
<div class="callout info">
477+
<strong>Connections Preserved:</strong> Unlike trees, forests can include connection data when
478+
saved. If you saved after calling <code>connect()</code>, the connection geometry and parameters
479+
are restored on load.
480+
</div>
481+
</section>
482+
391483
<!-- Examples Section -->
392484
<section id="examples" class="api-section">
393485
<h2>Examples</h2>

0 commit comments

Comments
 (0)