1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
//! # bevy_symbios_shape
//!
//! Bevy integration for [`symbios-shape`](https://crates.io/crates/symbios-shape) —
//! a CGA Shape Grammar engine for procedural architecture.
//!
//! ## Quick start
//!
//! ```ignore
//! use bevy::prelude::*;
//! use bevy_symbios_shape::prelude::*;
//! use symbios_shape::{Interpreter, Scope, grammar::parse_ops};
//!
//! fn main() {
//! App::new()
//! .add_plugins((DefaultPlugins, BevySymbiosShapePlugin))
//! .add_systems(Startup, setup)
//! .run();
//! }
//!
//! fn setup(
//! mut commands: Commands,
//! registry: Res<ShapeRegistry>,
//! mut meshes: ResMut<Assets<Mesh>>,
//! mut materials: ResMut<Assets<StandardMaterial>>,
//! mut cache: ResMut<ShapeMeshCache>,
//! ) {
//! let mut interp = Interpreter::new();
//! interp.add_rule("Lot", parse_ops("Extrude(12) Split(Y) { 3: Ground | ~1: Upper | 2: Roof }").unwrap());
//! interp.add_rule("Ground", parse_ops(r#"I("GroundFloor")"#).unwrap());
//! interp.add_rule("Upper", parse_ops(r#"I("Floor")"#).unwrap());
//! interp.add_rule("Roof", parse_ops(r#"Taper(0.8) I("Roof")"#).unwrap());
//!
//! let footprint = Scope::new(
//! symbios_shape::Vec3::ZERO,
//! symbios_shape::Quat::IDENTITY,
//! symbios_shape::Vec3::new(10.0, 0.0, 10.0),
//! );
//!
//! commands
//! .spawn_shape(&interp, footprint, "Lot", ®istry, &mut meshes, &mut materials, &mut cache)
//! .unwrap();
//! }
//! ```
//!
//! ## Modules
//!
//! | Module | Purpose |
//! |---|---|
//! | [`cache`] | [`ShapeMeshCache`] — cross-spawn procedural mesh cache with hit/miss counters |
//! | [`events`] | [`SpawnShapeRequest`] / [`SpawnShapeSpawned`] / [`SpawnShapeFailed`] event surface |
//! | [`mass`] | [`TerminalMass`] component carrying upstream `MassProperties` |
//! | [`mesh`] | `build_profiled_mesh` / `build_tapered_cuboid` — procedural mesh generation |
//! | `mutation` | `mutation` feature only — texture-config evolution plumbing |
//! | [`query`] | [`LastDerivedModel`] resource exposing the most recent `ShapeModel` for spatial queries |
//! | [`registry`] | [`ShapeRegistry`] — asset routing table (mesh + material IDs → handles) |
//! | [`snap`] | [`SnapPlanes`] resource exposing `RegSnap("…")` recordings |
//! | [`spawner`] | [`SpawnShapeExt`] — `Commands` extension trait |
//! | [`transform`] | [`scope_to_transform`] — `Scope` → Bevy `Transform` with f64→f32 + corner-to-centroid offset |
//!
//! ## Cargo features
//!
//! - `egui` (off by default) — pulls in [`bevy_egui`](https://crates.io/crates/bevy_egui).
//! Reserved for inspection/editor UIs built on top of the crate; the core
//! pipeline does not depend on it.
//! - `mutation` (off by default) — enables the `mutation` module, which
//! wires [`bevy_symbios_texture`](https://crates.io/crates/bevy_symbios_texture)
//! procedural texture configs into a Bevy observer pipeline so shape-grammar
//! materials can be evolved via `symbios_genetics::Genotype`.
pub use ShapeMeshCache;
pub use ;
pub use TerminalMass;
pub use ;
pub use LastDerivedModel;
pub use ShapeRegistry;
pub use ;
pub use SpawnShapeExt;
pub use scope_to_transform;
pub use ;
/// Convenience re-exports for the most common types.
/// Bevy plugin that wires the crate's resources and observer into an [`App`].
///
/// Add this plugin to your [`App`] alongside [`DefaultPlugins`]:
///
/// ```ignore
/// App::new()
/// .add_plugins((DefaultPlugins, BevySymbiosShapePlugin))
/// // ...
/// ```
///
/// The plugin installs the following [`Resource`]s (each in their `Default`
/// state) and observer:
///
/// - [`ShapeRegistry`] — asset routing table; populate it before any
/// `spawn_shape` call so terminals can resolve registered scenes/materials.
/// - [`SnapPlanes`] — overwritten by every `spawn_shape` call with the
/// `RegSnap("…")` planes recorded during derivation.
/// - [`LastDerivedModel`] — overwritten by every `spawn_shape` call with the
/// full upstream [`ShapeModel`][symbios_shape::ShapeModel] for spatial
/// queries.
/// - [`ShapeMeshCache`] — cross-spawn procedural mesh handle cache.
/// - An observer for [`SpawnShapeRequest`] that performs the derivation +
/// spawn and triggers [`SpawnShapeSpawned`] / [`SpawnShapeFailed`].
///
/// [`App`]: bevy::prelude::App
/// [`DefaultPlugins`]: bevy::prelude::DefaultPlugins
/// [`Resource`]: bevy::prelude::Resource
;