@@ -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 >
0 commit comments