diff --git a/.zenodo.json b/.zenodo.json index 3c2ee45..579ba97 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -52,6 +52,33 @@ { "id": "021nxhr62::2118240" } + ], + "references": [ + "Blender Development Team (2026). Blender (Version 5.1) [Computer software]. https://www.blender.org", + "Contreras-Figueroa, G. & Aragón, J. L. (2023). A mathematical model for mollusc shells based on parametric surfaces and the construction of theoretical morphospaces. Diversity 15, 431. https://doi.org/10.3390/d15030431", + "Okabe, T. & Yoshimura, J. (2017). Optimal designs of mollusk shells from bivalves to snails. Scientific Reports 7, 42445. https://doi.org/10.1038/srep42445", + "Porto, A. MorphoWeave: Atlas-based 3D landmark transfer and statistical shape modeling. GitHub repository. https://github.com/agporto/SlicerMorphoWeave" + ], + "related_identifiers": [ + { + "identifier": "https://www.blender.org", + "relation": "requires", + "resource_type": "software" + }, + { + "identifier": "10.3390/d15030431", + "relation": "cites", + "resource_type": "publication-article" + }, + { + "identifier": "10.1038/srep42445", + "relation": "cites", + "resource_type": "publication-article" + }, + { + "identifier": "https://github.com/agporto/SlicerMorphoWeave", + "relation": "cites", + "resource_type": "software" + } ] } - diff --git a/README.md b/README.md index 9ac0a65..fecf86d 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ TraitBlender is a Blender add-on for generating museum-style images and 3D meshe - **Shell (Default)** — A 3D shell morphospace that combines the parametric coiling model of [Contreras-Figueroa & Aragón (2023)](https://doi.org/10.3390/d15030431) with thickness allometry from [Okabe & Yoshimura (2017)](https://doi.org/10.1038/srep42445). Traits control whorl expansion, aperture shape, ribbing, and scaling; hyperparameters tune mesh resolution and options. - **Circle Grid** — A simple morphospace (e.g. for testing): a gridded plane of circles with configurable traits. -- **ATLAS** — Deforms a template mesh from an [ATLAS DATABASE](https://github.com/agporto/ATLAS) export using PCA on dense correspondences and local RBF interpolation (same workflow as the ATLAS DATABASE explorer). +- **MorphoWeave** — Deforms a template mesh from a [MorphoWeave](https://github.com/agporto/SlicerMorphoWeave) export using PCA on dense correspondences and local RBF interpolation (same workflow as the MorphoWeave Model Library / SSM Explorer). **Dataset import, editing, and saving** — Specimen trait values are read from CSV, TSV, or Excel. The built-in dataset editor supports filtering, sorting, pagination, and saving changes back to file, so you can curate and tweak trait tables without leaving Blender. diff --git a/traitblender/assets/morphospace_modules/ATLAS/morphospace/__init__.py b/traitblender/assets/morphospace_modules/ATLAS/morphospace/__init__.py deleted file mode 100644 index 9e41742..0000000 --- a/traitblender/assets/morphospace_modules/ATLAS/morphospace/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -from .atlas_morphospace import ( - generate_atlas_sample, - pc_values_from_trait_kwargs, - resolve_n_modes_for_hyperparams, -) -from .atlas_morphospace_sample import AtlasMorphospaceSample - -__all__ = [ - "generate_atlas_sample", - "AtlasMorphospaceSample", - "pc_values_from_trait_kwargs", - "resolve_n_modes_for_hyperparams", -] diff --git a/traitblender/assets/morphospace_modules/ATLAS/__init__.py b/traitblender/assets/morphospace_modules/MorphoWeave/__init__.py similarity index 69% rename from traitblender/assets/morphospace_modules/ATLAS/__init__.py rename to traitblender/assets/morphospace_modules/MorphoWeave/__init__.py index 402a612..17b9446 100644 --- a/traitblender/assets/morphospace_modules/ATLAS/__init__.py +++ b/traitblender/assets/morphospace_modules/MorphoWeave/__init__.py @@ -1,20 +1,21 @@ """ -ATLAS morphospace: template-centered PCA on dense correspondences + Local RBF warp. +MorphoWeave morphospace: template-centered PCA on dense correspondences + Local RBF warp. -Traits ``pc1`` … ``pcK`` are σ-multiples (ATLAS DATABASE sliders). Reconstruction: -``target = template_dense + Σ z_i √(λ_i) mode_i``, then Local RBF mesh warp (LPS/RAS aware). +Traits ``pc1`` … ``pcK`` are σ-multiples (MorphoWeave Model Library / SSM Explorer sliders). +Reconstruction: ``target = template_dense + Σ z_i √(λ_i) mode_i``, then Local RBF mesh warp +(LPS/RAS aware). """ from __future__ import annotations from .morphospace import ( - generate_atlas_sample, + generate_morphoweave_sample, pc_values_from_trait_kwargs, resolve_n_modes_for_hyperparams, ) from .orientations import ORIENTATIONS -NAME = "ATLAS" +NAME = "MorphoWeave" HYPERPARAMETERS = { "database_dir": "", @@ -33,9 +34,9 @@ def get_trait_parameters_with_defaults(merged_hyperparameters): return {f"pc{i}": 0.0 for i in range(1, n + 1)} -def sample(name="ATLAS", hyperparameters=None, **traits): +def sample(name="MorphoWeave", hyperparameters=None, **traits): """Generate a specimen; PC coefficients are passed as pc1, pc2, … keyword traits.""" - return generate_atlas_sample( + return generate_morphoweave_sample( name, hyperparameters or {}, pc_values_from_trait_kwargs(traits), @@ -48,6 +49,6 @@ def sample(name="ATLAS", hyperparameters=None, **traits): "HYPERPARAMETERS", "ORIENTATIONS", "get_trait_parameters_with_defaults", - "generate_atlas_sample", + "generate_morphoweave_sample", "resolve_n_modes_for_hyperparams", ] diff --git a/traitblender/assets/morphospace_modules/MorphoWeave/morphospace/__init__.py b/traitblender/assets/morphospace_modules/MorphoWeave/morphospace/__init__.py new file mode 100644 index 0000000..a0b97c1 --- /dev/null +++ b/traitblender/assets/morphospace_modules/MorphoWeave/morphospace/__init__.py @@ -0,0 +1,13 @@ +from .morphoweave_morphospace import ( + generate_morphoweave_sample, + pc_values_from_trait_kwargs, + resolve_n_modes_for_hyperparams, +) +from .morphoweave_morphospace_sample import MorphoWeaveMorphospaceSample + +__all__ = [ + "generate_morphoweave_sample", + "MorphoWeaveMorphospaceSample", + "pc_values_from_trait_kwargs", + "resolve_n_modes_for_hyperparams", +] diff --git a/traitblender/assets/morphospace_modules/ATLAS/morphospace/atlas_core.py b/traitblender/assets/morphospace_modules/MorphoWeave/morphospace/morphoweave_core.py similarity index 98% rename from traitblender/assets/morphospace_modules/ATLAS/morphospace/atlas_core.py rename to traitblender/assets/morphospace_modules/MorphoWeave/morphospace/morphoweave_core.py index 3a60ff4..deb2bac 100644 --- a/traitblender/assets/morphospace_modules/ATLAS/morphospace/atlas_core.py +++ b/traitblender/assets/morphospace_modules/MorphoWeave/morphospace/morphoweave_core.py @@ -1,7 +1,7 @@ """ -ATLAS DATABASE core (PCA + Local RBF), matching agporto/ATLAS DATABASE explorer. +MorphoWeave Model Library core (PCA + Local RBF), matching agporto/SlicerMorphoWeave. -Ported from the working ATLASViewer reference implementation: +Ported from the MorphoWeave / former ATLASViewer reference implementation: - Template-centered PCA: target = template_dense + sum_i (z_i * sqrt(lambda_i) * mode_i) - Local RBF: k=min(32, n_landmarks), Gaussian weights, h = 75th percentile k-th NN distance - LPS/RAS: dense landmarks and SSM in RAS; template PLY typically LPS on disk @@ -21,7 +21,7 @@ def resolve_database_paths(database_dir: str | Path) -> dict[str, Path]: - """Resolve model, dense, sparse (optional), and ssm paths in an ATLAS DATABASE folder.""" + """Resolve model, dense, sparse (optional), and ssm paths in a MorphoWeave Model Library / DATABASE folder.""" root = Path(database_dir).expanduser().resolve() if not root.is_dir(): raise FileNotFoundError(f"Database folder not found: {root}") @@ -254,7 +254,7 @@ def ssm_std_devs(eigenvalues: np.ndarray) -> np.ndarray: return np.sqrt(np.maximum(np.asarray(eigenvalues, dtype=np.float64).ravel(), 0.0)) -def atlas_pc_coefficients( +def morphoweave_pc_coefficients( sigma_weights: np.ndarray | Sequence[float], eigenvalues: np.ndarray, ) -> np.ndarray: @@ -287,7 +287,7 @@ def reconstruct_dense_target( if k == 0 or np.allclose(z[:k], 0.0): return template.copy() - coeff = atlas_pc_coefficients(z[:k], ev[:k]) + coeff = morphoweave_pc_coefficients(z[:k], ev[:k]) agg = np.tensordot(modes_arr[..., :k], coeff, axes=(2, 0)) return template + agg diff --git a/traitblender/assets/morphospace_modules/ATLAS/morphospace/atlas_morphospace.py b/traitblender/assets/morphospace_modules/MorphoWeave/morphospace/morphoweave_morphospace.py similarity index 82% rename from traitblender/assets/morphospace_modules/ATLAS/morphospace/atlas_morphospace.py rename to traitblender/assets/morphospace_modules/MorphoWeave/morphospace/morphoweave_morphospace.py index a18b6e6..bbf5b7e 100644 --- a/traitblender/assets/morphospace_modules/ATLAS/morphospace/atlas_morphospace.py +++ b/traitblender/assets/morphospace_modules/MorphoWeave/morphospace/morphoweave_morphospace.py @@ -1,5 +1,5 @@ """ -ATLAS morphospace sample generation (TraitBlender wrapper around atlas_core). +MorphoWeave morphospace sample generation (TraitBlender wrapper around morphoweave_core). """ from __future__ import annotations @@ -9,8 +9,8 @@ import bpy import numpy as np -from .atlas_core import build_deformed_mesh_arrays, load_ssm, resolve_database_paths -from .atlas_morphospace_sample import AtlasMorphospaceSample +from .morphoweave_core import build_deformed_mesh_arrays, load_ssm, resolve_database_paths +from .morphoweave_morphospace_sample import MorphoWeaveMorphospaceSample def resolve_n_modes_for_hyperparams(hyperparameters: dict | None) -> int | None: @@ -49,30 +49,31 @@ def pc_values_from_trait_kwargs(traits: dict) -> list[float]: def _log(msg: str) -> None: - print(f"[ATLAS] {msg}") + print(f"[MorphoWeave] {msg}") -def generate_atlas_sample( +def generate_morphoweave_sample( name: str, hyperparameters: dict | None, pc_values: list[float], -) -> AtlasMorphospaceSample: +) -> MorphoWeaveMorphospaceSample: hp = dict(hyperparameters or {}) db_raw = (hp.get("database_dir") or hp.get("database_path") or "").strip() if not db_raw: raise ValueError( - "ATLAS morphospace: set hyperparameter 'database_dir' to your DATABASE folder " + "MorphoWeave morphospace: set hyperparameter 'database_dir' to your " + "MorphoWeave Model Library / DATABASE folder " "(manifest + template model + dense correspondences + ssm_model.npz)." ) db_root = Path(bpy.path.abspath(db_raw)) if not db_root.is_dir(): - raise ValueError(f"ATLAS database_dir is not a directory: {db_root}") + raise ValueError(f"MorphoWeave database_dir is not a directory: {db_root}") n_comp_cfg = max(0, int(hp.get("n_components", 10))) scale = float(hp.get("scale", 1.0)) if scale <= 0.0: - raise ValueError("ATLAS hyperparameter 'scale' must be positive") + raise ValueError("MorphoWeave hyperparameter 'scale' must be positive") paths = resolve_database_paths(db_root) ssm = load_ssm(paths) @@ -117,4 +118,4 @@ def generate_atlas_sample( _log(f" mesh: {vertices.shape[0]} verts, {len(faces)} faces") verts = [tuple(map(float, row)) for row in vertices] - return AtlasMorphospaceSample(name, verts, faces) + return MorphoWeaveMorphospaceSample(name, verts, faces) diff --git a/traitblender/assets/morphospace_modules/ATLAS/morphospace/atlas_morphospace_sample.py b/traitblender/assets/morphospace_modules/MorphoWeave/morphospace/morphoweave_morphospace_sample.py similarity index 84% rename from traitblender/assets/morphospace_modules/ATLAS/morphospace/atlas_morphospace_sample.py rename to traitblender/assets/morphospace_modules/MorphoWeave/morphospace/morphoweave_morphospace_sample.py index 29ed045..d48e07c 100644 --- a/traitblender/assets/morphospace_modules/ATLAS/morphospace/atlas_morphospace_sample.py +++ b/traitblender/assets/morphospace_modules/MorphoWeave/morphospace/morphoweave_morphospace_sample.py @@ -1,9 +1,9 @@ -"""Blender mesh creation for an ATLAS warped template.""" +"""Blender mesh creation for a MorphoWeave warped template.""" import bpy -class AtlasMorphospaceSample: +class MorphoWeaveMorphospaceSample: def __init__(self, name: str, vertices: list, faces: list): self.name = name self.vertices = vertices diff --git a/traitblender/assets/morphospace_modules/ATLAS/orientations/__init__.py b/traitblender/assets/morphospace_modules/MorphoWeave/orientations/__init__.py similarity index 78% rename from traitblender/assets/morphospace_modules/ATLAS/orientations/__init__.py rename to traitblender/assets/morphospace_modules/MorphoWeave/orientations/__init__.py index debe2ec..1ea0583 100644 --- a/traitblender/assets/morphospace_modules/ATLAS/orientations/__init__.py +++ b/traitblender/assets/morphospace_modules/MorphoWeave/orientations/__init__.py @@ -1,5 +1,5 @@ """ -ATLAS specimen orientations. +MorphoWeave specimen orientations. Default: table placement only (tb_location). Other views: rotate one axis by n·π/4 (n = 1..7), origin to bounds, tb_location reset — then apply_orientation bakes rotation. @@ -13,7 +13,7 @@ import bpy -def _orient_atlas_default(sample_obj): +def _orient_morphoweave_default(sample_obj): sample_obj.tb_location = (0.0, 0.0, 0.0) @@ -28,13 +28,13 @@ def _pi_multiplier_label(n_quarters: int) -> str: return f"{num}/{den}" -def _make_atlas_axis_rotation(axis: str, n_quarters: int): +def _make_morphoweave_axis_rotation(axis: str, n_quarters: int): angle = (math.pi / 4.0) * n_quarters label = _pi_multiplier_label(n_quarters) name = f"{axis} {label} π Rotation" def orient(sample_obj): - _orient_atlas_default(sample_obj) + _orient_morphoweave_default(sample_obj) if axis == "X": sample_obj.tb_rotation = (angle, 0.0, 0.0) elif axis == "Y": @@ -48,15 +48,15 @@ def orient(sample_obj): sample_obj.tb_location = (0.0, 0.0, 0.0) bpy.context.view_layer.update() - orient.__name__ = f"_orient_atlas_{axis}_{n_quarters}q" + orient.__name__ = f"_orient_morphoweave_{axis}_{n_quarters}q" return name, orient def _build_orientations() -> dict: - out: dict = {"Default": _orient_atlas_default} + out: dict = {"Default": _orient_morphoweave_default} for axis in ("X", "Y", "Z"): for n in range(1, 8): - key, fn = _make_atlas_axis_rotation(axis, n) + key, fn = _make_morphoweave_axis_rotation(axis, n) out[key] = fn return out diff --git a/traitblender/core/config/templates/meshes.py b/traitblender/core/config/templates/meshes.py index 08565ea..6a4abe1 100644 --- a/traitblender/core/config/templates/meshes.py +++ b/traitblender/core/config/templates/meshes.py @@ -36,7 +36,7 @@ class MeshesConfig(TraitBlenderConfig): description=( "If enabled (default), apply the morphospace Default orientation before exporting " "meshes (table placement). Disable to export the generated mesh as-is—useful for " - "ATLAS, where the SSM already provides a consistent PCA-aligned frame" + "MorphoWeave, where the SSM already provides a consistent PCA-aligned frame" ), default=True, ) diff --git a/traitblender/core/datasets/traitblender_dataset.py b/traitblender/core/datasets/traitblender_dataset.py index cc8a35a..4a054ab 100644 --- a/traitblender/core/datasets/traitblender_dataset.py +++ b/traitblender/core/datasets/traitblender_dataset.py @@ -323,7 +323,7 @@ def _get_default_dataframe(self): def _ensure_virtual_dataset_traits_synced(self) -> None: """ No filepath: in-memory CSV. Morphospaces with ``get_trait_parameters_with_defaults`` - (e.g. ATLAS ``n_components``) may change expected trait columns — rewrite CSV to match + (e.g. MorphoWeave ``n_components``) may change expected trait columns — rewrite CSV to match so the editor and ``loc()`` stay consistent. """ if self.filepath: diff --git a/traitblender/core/helpers/orientation_helpers.py b/traitblender/core/helpers/orientation_helpers.py index 599c31e..2b6f3d5 100644 --- a/traitblender/core/helpers/orientation_helpers.py +++ b/traitblender/core/helpers/orientation_helpers.py @@ -113,7 +113,7 @@ def make_euler_orientation(rx, ry, rz, default_fn=None): before bake), then origin at geometry bounds and table center. Local composition uses ``R_obj @ R_local`` so axes follow the specimen after Default - (works for Shell aperture alignment, ATLAS table Default, etc.). + (works for Shell aperture alignment, MorphoWeave table Default, etc.). Args: rx, ry, rz: Local Euler rotation in radians (object rotation_euler order). diff --git a/traitblender/core/morphospaces/list_morphospaces.py b/traitblender/core/morphospaces/list_morphospaces.py index 53776fa..e11316e 100644 --- a/traitblender/core/morphospaces/list_morphospaces.py +++ b/traitblender/core/morphospaces/list_morphospaces.py @@ -6,7 +6,7 @@ from .get_orientations import get_orientations_for_morphospace # GUI dropdown order (folder names under morphospace_modules/) -_MORPHOSPACE_ORDER = ("Shell", "CircleGrid", "ATLAS") +_MORPHOSPACE_ORDER = ("Shell", "CircleGrid", "MorphoWeave") def list_morphospaces(): diff --git a/traitblender/core/morphospaces/trait_params.py b/traitblender/core/morphospaces/trait_params.py index 6903b47..3fde175 100644 --- a/traitblender/core/morphospaces/trait_params.py +++ b/traitblender/core/morphospaces/trait_params.py @@ -39,7 +39,7 @@ def get_trait_parameters_with_defaults_for_morphospace(morphospace_name, context Get trait parameters and their default values for a morphospace. If the module defines ``get_trait_parameters_with_defaults(merged_hyperparameters)``, that - return value is used (e.g. ATLAS: PC1..PCn from ``n_components``, capped by SSM mode count). + return value is used (e.g. MorphoWeave: PC1..PCn from ``n_components``, capped by SSM mode count). Otherwise parameters are inferred from ``sample()``'s signature. diff --git a/traitblender/docs/api/scene-assets.md b/traitblender/docs/api/scene-assets.md index 2d13609..b4279a8 100644 --- a/traitblender/docs/api/scene-assets.md +++ b/traitblender/docs/api/scene-assets.md @@ -151,7 +151,7 @@ This reference focuses on the user-facing operators and properties you will use

bpy.context.scene.traitblender_config.meshes.orient_before_export

-

If True (default), apply Default orientation before pipeline mesh export (backward compatible). If False, export the generated mesh as-is—recommended for ATLAS PCA-aligned meshes. Does not affect imaging orientations used for renders. See Configuration Files.

+

If True (default), apply Default orientation before pipeline mesh export (backward compatible). If False, export the generated mesh as-is—recommended for MorphoWeave PCA-aligned meshes. Does not affect imaging orientations used for renders. See Configuration Files.


diff --git a/traitblender/docs/configuration/config-files.md b/traitblender/docs/configuration/config-files.md index 71a78f0..ffe283a 100644 --- a/traitblender/docs/configuration/config-files.md +++ b/traitblender/docs/configuration/config-files.md @@ -117,7 +117,7 @@ TraitBlender config files are **YAML** files that store the settings you see in

meshes

@@ -275,7 +275,7 @@ imaging: meshes: file_export_type: obj save_meshes: true - # ATLAS: keep SSM/PCA frame (skip Default table placement before export) + # MorphoWeave: keep SSM/PCA frame (skip Default table placement before export) # orient_before_export: false ``` @@ -450,7 +450,7 @@ When `meshes.save_meshes` is `true`, the simulation pipeline writes one mesh per | Value | Mesh file contents | |-------|--------------------| | `true` (default) | Morphospace **Default** applied first (table placement). Same behavior as earlier TraitBlender releases. | -| `false` | Export the mesh as generated, with no Default/table orientation. Prefer this for **ATLAS**, where the SSM already lives in a shared PCA-aligned frame. Imaging orientations still apply afterward for rendered images only. | +| `false` | Export the mesh as generated, with no Default/table orientation. Prefer this for **MorphoWeave**, where the SSM already lives in a shared PCA-aligned frame. Imaging orientations still apply afterward for rendered images only. | ```yaml meshes: diff --git a/traitblender/docs/getting-started/quick-start.md b/traitblender/docs/getting-started/quick-start.md index ddd8f09..21d729a 100644 --- a/traitblender/docs/getting-started/quick-start.md +++ b/traitblender/docs/getting-started/quick-start.md @@ -78,11 +78,11 @@ Before starting, ensure you have: - **Shell (Default)** — parametric mollusc shells ([Contreras-Figueroa & Aragón](https://www.mdpi.com/1424-2818/15/3/431); thickness from [Okabe & Yoshimura](https://doi.org/10.1038/srep42445)) - **Circle Grid** — simple test morphospace (cube with a 4×4 grid of circles) - - **ATLAS** — deform a template mesh from an [ATLAS DATABASE](https://github.com/agporto/ATLAS) export using PCA + local RBF ([details](../morphospaces/atlas.md)) + - **MorphoWeave** — deform a template mesh from a [MorphoWeave](https://github.com/agporto/SlicerMorphoWeave) export using PCA + local RBF ([details](../morphospaces/morphoweave.md)) Select the morphospace that matches your dataset. - For **ATLAS**, set **`database_dir`** under Configuration → morphospace hyperparameters before generating samples. + For **MorphoWeave**, set **`database_dir`** under Configuration → morphospace hyperparameters before generating samples. ??? note "Step 4: Import and Manage Datasets" Expand the **"4 Datasets"** panel. @@ -155,7 +155,7 @@ Before starting, ensure you have: 1. Choose the mesh export type. 2. Enable **Save Meshes** if you want the simulation pipeline to export meshes. - 3. Optionally disable **Orient before export** to save meshes in the morphospace/SSM frame (recommended for ATLAS); leave it on (default) to apply Default table placement first. + 3. Optionally disable **Orient before export** to save meshes in the morphospace/SSM frame (recommended for MorphoWeave); leave it on (default) to apply Default table placement first. 4. You can also use **Export Mesh** to save the current sample manually. ??? note "Step 8: Imaging" diff --git a/traitblender/docs/images/Morphospace Samples/atlas-1.png b/traitblender/docs/images/Morphospace Samples/morphoweave-1.png similarity index 100% rename from traitblender/docs/images/Morphospace Samples/atlas-1.png rename to traitblender/docs/images/Morphospace Samples/morphoweave-1.png diff --git a/traitblender/docs/images/Morphospace Samples/atlas-2.png b/traitblender/docs/images/Morphospace Samples/morphoweave-2.png similarity index 100% rename from traitblender/docs/images/Morphospace Samples/atlas-2.png rename to traitblender/docs/images/Morphospace Samples/morphoweave-2.png diff --git a/traitblender/docs/images/Morphospace Samples/atlas-3.png b/traitblender/docs/images/Morphospace Samples/morphoweave-3.png similarity index 100% rename from traitblender/docs/images/Morphospace Samples/atlas-3.png rename to traitblender/docs/images/Morphospace Samples/morphoweave-3.png diff --git a/traitblender/docs/images/morphoweave-logo.png b/traitblender/docs/images/morphoweave-logo.png new file mode 100644 index 0000000..19a038a Binary files /dev/null and b/traitblender/docs/images/morphoweave-logo.png differ diff --git a/traitblender/docs/morphospaces/atlas.md b/traitblender/docs/morphospaces/morphoweave.md similarity index 64% rename from traitblender/docs/morphospaces/atlas.md rename to traitblender/docs/morphospaces/morphoweave.md index ebac032..a18e678 100644 --- a/traitblender/docs/morphospaces/atlas.md +++ b/traitblender/docs/morphospaces/morphoweave.md @@ -1,21 +1,25 @@ -# ATLAS +# MorphoWeave -The **ATLAS** morphospace deforms a template surface mesh using a statistical shape model (SSM) exported from an [ATLAS DATABASE](https://github.com/agporto/ATLAS) folder. TraitBlender matches the ATLAS DATABASE explorer workflow: +
+ MorphoWeave logo +
+ +The **MorphoWeave** morphospace deforms a template surface mesh using a statistical shape model (SSM) exported from a [MorphoWeave](https://github.com/agporto/SlicerMorphoWeave) Model Library / DATABASE folder. TraitBlender matches the MorphoWeave SSM Explorer workflow: 1. **Dense PCA** — reconstruct target landmark positions from principal-component weights. 2. **Local RBF** — warp the template mesh so it follows the landmark motion. -Traits are **multiples of the per-mode standard deviation** (σ), the same units as the PC sliders in ATLAS DATABASE and 3D Slicer. +Traits are **multiples of the per-mode standard deviation** (σ), the same units as the PC sliders in MorphoWeave’s SSM Explorer and 3D Slicer.
- ATLAS morphospace sample 1 - ATLAS morphospace sample 2 - ATLAS morphospace sample 3 + MorphoWeave morphospace sample 1 + MorphoWeave morphospace sample 2 + MorphoWeave morphospace sample 3
??? note "Prerequisites" - You need a complete ATLAS DATABASE export directory on disk. TraitBlender resolves these files automatically (via `manifest.json` when present, or by filename patterns): + You need a complete MorphoWeave Model Library export directory on disk. TraitBlender resolves these files automatically (via `manifest.json` when present, or by filename patterns): | Role | Typical filename | |------|------------------| @@ -27,9 +31,9 @@ Traits are **multiples of the per-mode standard deviation** (σ), the same units ```yaml morphospace: - name: ATLAS + name: MorphoWeave hyperparams: - database_dir: "C:/path/to/your/ATLAS_DATABASE_export" + database_dir: "C:/path/to/your/MorphoWeave_ModelLibrary_export" n_components: 10 scale: 1.0 ``` @@ -42,7 +46,7 @@ Traits are `pc1`, `pc2`, … up to the number set by the **`n_components`** hype | Trait | Default | Description | Typical range | |-------|---------|-------------|----------------| -| `pc1` … `pcN` | `0.0` | Weight on PC *i* in units of standard deviation (√λᵢ). `0` = no contribution along that mode. | Often explored in roughly **−3** to **+3** (same as ATLAS DATABASE sliders). | +| `pc1` … `pcN` | `0.0` | Weight on PC *i* in units of standard deviation (√λᵢ). `0` = no contribution along that mode. | Often explored in roughly **−3** to **+3** (same as MorphoWeave SSM Explorer sliders). | The number of trait columns in your dataset should match **`n_components`**. When you change `n_components` in the Configuration panel, regenerate or re-import the dataset so column headers stay in sync. @@ -58,13 +62,13 @@ specimen_b,-2.0,1.0,0.0 | Hyperparameter | Default | Description | Typical range / notes | |----------------|---------|-------------|------------------------| -| `database_dir` | *(empty)* | Absolute or Blender-relative path to the ATLAS DATABASE folder. **Required** before generating samples. | Folder containing `manifest.json` (recommended) or the standard file set. | +| `database_dir` | *(empty)* | Absolute or Blender-relative path to the MorphoWeave Model Library / DATABASE folder. **Required** before generating samples. | Folder containing `manifest.json` (recommended) or the standard file set. | | `n_components` | `10` | How many PCs appear as dataset traits (`pc1` … `pcN`). | At least `1`; cannot exceed the number of modes in `ssm_model.npz`. | | `scale` | `1.0` | Uniform scale applied to deformed vertex positions **after** the RBF warp. | Positive; `1.0` = no extra scaling. | ## Orientations -ATLAS defines many named orientations for multi-view imaging: +MorphoWeave defines many named orientations for multi-view imaging: - **Default** — specimen centered on the table (no rotation). - **X / Y / Z *n*/4 π Rotation** — rotations in π/4 steps about each axis (for comparable views across specimens). @@ -75,7 +79,7 @@ Select an orientation in the **Orientations** panel and click **Apply**, or incl ## Mesh export -For 3D analysis, prefer exporting ATLAS meshes **without** Default table placement so they stay in the SSM/PCA frame: +For 3D analysis, prefer exporting MorphoWeave meshes **without** Default table placement so they stay in the SSM/PCA frame: ```yaml meshes: @@ -87,5 +91,5 @@ meshes: ## References -- Porto, A. (2025). ATLAS: Automated Template-based Landmark Alignment System. GitHub repository. https://github.com/agporto/ATLAS -- TraitBlender’s implementation follows the ATLAS DATABASE explorer (template-centered PCA + local RBF deformer). +- Porto, A. MorphoWeave: Atlas-based 3D landmark transfer and statistical shape modeling. GitHub repository. https://github.com/agporto/SlicerMorphoWeave +- TraitBlender’s implementation follows the MorphoWeave Model Library / SSM Explorer workflow (template-centered PCA + local RBF deformer). diff --git a/traitblender/docs/morphospaces/overview.md b/traitblender/docs/morphospaces/overview.md index b5090b4..a043552 100644 --- a/traitblender/docs/morphospaces/overview.md +++ b/traitblender/docs/morphospaces/overview.md @@ -4,9 +4,9 @@ TraitBlender currently includes three morphospaces: - **[Shell (Default)](shell.md)** – a 3D shell model based on Contreras-Figueroa & Aragón (2023) - **[Circle Grid](circle-grid.md)** – a white cube with a 4×4 grid of black circles on top -- **[ATLAS](atlas.md)** – PCA + local RBF deformation of a template mesh from an ATLAS DATABASE export +- **[MorphoWeave](morphoweave.md)** – PCA + local RBF deformation of a template mesh from a MorphoWeave Model Library export -Each morphospace has a **name** (e.g. "Shell (Default)", "Circle Grid", "ATLAS") used in the GUI and in config files, and: +Each morphospace has a **name** (e.g. "Shell (Default)", "Circle Grid", "MorphoWeave") used in the GUI and in config files, and: - **traits** – columns in the dataset (per-specimen values) - **hyperparameters** – extra settings that affect how the model is generated (set in the Configuration panel) diff --git a/traitblender/docs/morphospaces/shell.md b/traitblender/docs/morphospaces/shell.md index 037deaa..e1002d6 100644 --- a/traitblender/docs/morphospaces/shell.md +++ b/traitblender/docs/morphospaces/shell.md @@ -79,5 +79,5 @@ Shell defines built-in named orientations (including **Default**) for placing sp ## References -- Contreras-Figueroa, R. & Aragón, L. (2023). A mathematical model for mollusc shells based on parametric surfaces and the application to *Conus* shells. *Diversity* **15**, 431. [https://doi.org/10.3390/d15030431](https://doi.org/10.3390/d15030431) +- Contreras-Figueroa, G. & Aragón, J. L. (2023). A mathematical model for mollusc shells based on parametric surfaces and the construction of theoretical morphospaces. *Diversity* **15**, 431. [https://doi.org/10.3390/d15030431](https://doi.org/10.3390/d15030431) - Okabe, T. & Yoshimura, J. (2017). Optimal designs of mollusk shells from bivalves to snails. *Scientific Reports* **7**, 42445. [https://doi.org/10.1038/srep42445](https://doi.org/10.1038/srep42445) diff --git a/traitblender/mkdocs.yml b/traitblender/mkdocs.yml index dc8c7b2..d2af152 100644 --- a/traitblender/mkdocs.yml +++ b/traitblender/mkdocs.yml @@ -80,7 +80,7 @@ nav: - Overview: morphospaces/overview.md - Shell (Default): morphospaces/shell.md - Circle Grid: morphospaces/circle-grid.md - - ATLAS: morphospaces/atlas.md + - MorphoWeave: morphospaces/morphoweave.md - Tutorials: tutorials.md extra: diff --git a/traitblender/ui/operators/generate_morphospace_sample_op.py b/traitblender/ui/operators/generate_morphospace_sample_op.py index ee4320f..0121db6 100644 --- a/traitblender/ui/operators/generate_morphospace_sample_op.py +++ b/traitblender/ui/operators/generate_morphospace_sample_op.py @@ -77,7 +77,7 @@ def _norm_col(s: str) -> str: # Map dataset columns to function parameters (excluding hyperparameters). # Case-insensitive match so e.g. dataset column "S" maps to param "S". - # Morphospaces with **traits (e.g. ATLAS pc1..pcN) pass all non-species trait columns. + # Morphospaces with **traits (e.g. MorphoWeave pc1..pcN) pass all non-species trait columns. params = {} for column_name, value in row_data.items(): param_name = column_name.lower().replace(' ', '_') diff --git a/traitblender/ui/operators/imaging_pipeline_op.py b/traitblender/ui/operators/imaging_pipeline_op.py index 816fd4a..534721b 100644 --- a/traitblender/ui/operators/imaging_pipeline_op.py +++ b/traitblender/ui/operators/imaging_pipeline_op.py @@ -80,7 +80,7 @@ def _imaging_step(self, context): dataset.sample = name # When exporting unoriented meshes, skip Default on generate so the file - # matches the morphospace/SSM frame (e.g. ATLAS PCA alignment). + # matches the morphospace/SSM frame (e.g. MorphoWeave PCA alignment). apply_default = (not self._save_meshes) or self._orient_before_export bpy.ops.traitblender.generate_morphospace_sample( apply_default_orientation=apply_default