forked from StudioInfinity/dyna3
Pause realization while loading assemblies
This avoids redundant realizations as we set an assembly's regulators during loading. Adding some regulators to the low-curvature assembly confirms that the feature is working as intended.
This commit is contained in:
parent
5864017e6f
commit
40d665d8ac
2 changed files with 90 additions and 9 deletions
|
@ -6,7 +6,8 @@ use crate::{
|
||||||
AppState,
|
AppState,
|
||||||
engine,
|
engine,
|
||||||
engine::DescentHistory,
|
engine::DescentHistory,
|
||||||
assembly::{Assembly, InversiveDistanceRegulator, Point, Sphere}
|
assembly::{Assembly, InversiveDistanceRegulator, Point, Sphere},
|
||||||
|
specified::SpecifiedValue
|
||||||
};
|
};
|
||||||
|
|
||||||
/* DEBUG */
|
/* DEBUG */
|
||||||
|
@ -67,6 +68,7 @@ fn load_gen_assemb(assembly: &Assembly) {
|
||||||
// load an example assembly for testing. this code will be removed once we've
|
// load an example assembly for testing. this code will be removed once we've
|
||||||
// built a more formal test assembly system
|
// built a more formal test assembly system
|
||||||
fn load_low_curv_assemb(assembly: &Assembly) {
|
fn load_low_curv_assemb(assembly: &Assembly) {
|
||||||
|
// create the spheres
|
||||||
let a = 0.75_f64.sqrt();
|
let a = 0.75_f64.sqrt();
|
||||||
let _ = assembly.try_insert_element(
|
let _ = assembly.try_insert_element(
|
||||||
Sphere::new(
|
Sphere::new(
|
||||||
|
@ -132,6 +134,56 @@ fn load_low_curv_assemb(assembly: &Assembly) {
|
||||||
engine::sphere(2.0/3.0, 4.0/3.0 * a, 0.0, 1.0/3.0)
|
engine::sphere(2.0/3.0, 4.0/3.0 * a, 0.0, 1.0/3.0)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// impose the desired tangencies and make the sides planar
|
||||||
|
let index_range = 1..=3;
|
||||||
|
let [central, assemb_plane] = ["central", "assemb_plane"].map(
|
||||||
|
|id| assembly.elements_by_id.with_untracked(
|
||||||
|
|elts_by_id| elts_by_id[id].clone()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
let sides = index_range.clone().map(
|
||||||
|
|k| assembly.elements_by_id.with_untracked(
|
||||||
|
|elts_by_id| elts_by_id[&format!("side{k}")].clone()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
let corners = index_range.map(
|
||||||
|
|k| assembly.elements_by_id.with_untracked(
|
||||||
|
|elts_by_id| elts_by_id[&format!("corner{k}")].clone()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
for plane in [assemb_plane.clone()].into_iter().chain(sides.clone()) {
|
||||||
|
// fix the curvature of each plane
|
||||||
|
let curvature = plane.regulators().with_untracked(
|
||||||
|
|regs| regs.first().unwrap().clone()
|
||||||
|
);
|
||||||
|
curvature.set_point().set(SpecifiedValue::try_from("0".to_string()).unwrap());
|
||||||
|
}
|
||||||
|
let all_perpendicular = [central.clone()].into_iter()
|
||||||
|
.chain(sides.clone())
|
||||||
|
.chain(corners.clone());
|
||||||
|
for sphere in all_perpendicular {
|
||||||
|
// make each side and packed sphere perpendicular to the assembly plane
|
||||||
|
let right_angle = InversiveDistanceRegulator::new([sphere, assemb_plane.clone()]);
|
||||||
|
right_angle.set_point.set(SpecifiedValue::try_from("0".to_string()).unwrap());
|
||||||
|
assembly.insert_regulator(Rc::new(right_angle));
|
||||||
|
}
|
||||||
|
for sphere in sides.clone().chain(corners.clone()) {
|
||||||
|
// make each side and corner sphere tangent to the central sphere
|
||||||
|
let tangency = InversiveDistanceRegulator::new([sphere.clone(), central.clone()]);
|
||||||
|
tangency.set_point.set(SpecifiedValue::try_from("-1".to_string()).unwrap());
|
||||||
|
assembly.insert_regulator(Rc::new(tangency));
|
||||||
|
}
|
||||||
|
for (side_index, side) in sides.enumerate() {
|
||||||
|
// make each side tangent to the two adjacent corner spheres
|
||||||
|
for (corner_index, corner) in corners.clone().enumerate() {
|
||||||
|
if side_index != corner_index {
|
||||||
|
let tangency = InversiveDistanceRegulator::new([side.clone(), corner]);
|
||||||
|
tangency.set_point.set(SpecifiedValue::try_from("-1".to_string()).unwrap());
|
||||||
|
assembly.insert_regulator(Rc::new(tangency));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_pointed_assemb(assembly: &Assembly) {
|
fn load_pointed_assemb(assembly: &Assembly) {
|
||||||
|
@ -192,6 +244,9 @@ pub fn AddRemove() -> View {
|
||||||
let state = use_context::<AppState>();
|
let state = use_context::<AppState>();
|
||||||
let assembly = &state.assembly;
|
let assembly = &state.assembly;
|
||||||
|
|
||||||
|
// pause realization
|
||||||
|
assembly.keep_realized.set(false);
|
||||||
|
|
||||||
// clear state
|
// clear state
|
||||||
assembly.regulators.update(|regs| regs.clear());
|
assembly.regulators.update(|regs| regs.clear());
|
||||||
assembly.elements.update(|elts| elts.clear());
|
assembly.elements.update(|elts| elts.clear());
|
||||||
|
@ -206,6 +261,9 @@ pub fn AddRemove() -> View {
|
||||||
"pointed" => load_pointed_assemb(assembly),
|
"pointed" => load_pointed_assemb(assembly),
|
||||||
_ => ()
|
_ => ()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// resume realization
|
||||||
|
assembly.keep_realized.set(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -552,6 +552,10 @@ pub struct Assembly {
|
||||||
// indexing
|
// indexing
|
||||||
pub elements_by_id: Signal<BTreeMap<String, Rc<dyn Element>>>,
|
pub elements_by_id: Signal<BTreeMap<String, Rc<dyn Element>>>,
|
||||||
|
|
||||||
|
// realization control
|
||||||
|
pub keep_realized: Signal<bool>,
|
||||||
|
pub needs_realization: Signal<bool>,
|
||||||
|
|
||||||
// realization diagnostics
|
// realization diagnostics
|
||||||
pub realization_status: Signal<Result<(), String>>,
|
pub realization_status: Signal<Result<(), String>>,
|
||||||
pub descent_history: Signal<DescentHistory>
|
pub descent_history: Signal<DescentHistory>
|
||||||
|
@ -559,14 +563,30 @@ pub struct Assembly {
|
||||||
|
|
||||||
impl Assembly {
|
impl Assembly {
|
||||||
pub fn new() -> Assembly {
|
pub fn new() -> Assembly {
|
||||||
Assembly {
|
// create an assembly
|
||||||
|
let assembly = Assembly {
|
||||||
elements: create_signal(BTreeSet::new()),
|
elements: create_signal(BTreeSet::new()),
|
||||||
regulators: create_signal(BTreeSet::new()),
|
regulators: create_signal(BTreeSet::new()),
|
||||||
tangent: create_signal(ConfigSubspace::zero(0)),
|
tangent: create_signal(ConfigSubspace::zero(0)),
|
||||||
elements_by_id: create_signal(BTreeMap::default()),
|
elements_by_id: create_signal(BTreeMap::default()),
|
||||||
|
keep_realized: create_signal(true),
|
||||||
|
needs_realization: create_signal(false),
|
||||||
realization_status: create_signal(Ok(())),
|
realization_status: create_signal(Ok(())),
|
||||||
descent_history: create_signal(DescentHistory::new())
|
descent_history: create_signal(DescentHistory::new())
|
||||||
}
|
};
|
||||||
|
|
||||||
|
// realize the assembly whenever it becomes simultaneously true that
|
||||||
|
// we're trying to keep it realized and it needs realization
|
||||||
|
let assembly_for_effect = assembly.clone();
|
||||||
|
create_effect(move || {
|
||||||
|
let should_realize = assembly_for_effect.keep_realized.get()
|
||||||
|
&& assembly_for_effect.needs_realization.get();
|
||||||
|
if should_realize {
|
||||||
|
assembly_for_effect.realize();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assembly
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- inserting elements and regulators ---
|
// --- inserting elements and regulators ---
|
||||||
|
@ -627,7 +647,7 @@ impl Assembly {
|
||||||
regulators.update(|regs| regs.insert(regulator.clone()));
|
regulators.update(|regs| regs.insert(regulator.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the realization when the regulator becomes a constraint, or is
|
// request a realization when the regulator becomes a constraint, or is
|
||||||
// edited while acting as a constraint
|
// edited while acting as a constraint
|
||||||
let self_for_effect = self.clone();
|
let self_for_effect = self.clone();
|
||||||
create_effect(move || {
|
create_effect(move || {
|
||||||
|
@ -636,7 +656,7 @@ impl Assembly {
|
||||||
console_log!("Updated regulator with subjects {:?}", regulator.subjects());
|
console_log!("Updated regulator with subjects {:?}", regulator.subjects());
|
||||||
|
|
||||||
if regulator.try_activate() {
|
if regulator.try_activate() {
|
||||||
self_for_effect.realize();
|
self_for_effect.needs_realization.set(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -731,6 +751,9 @@ impl Assembly {
|
||||||
|
|
||||||
// save the tangent space
|
// save the tangent space
|
||||||
self.tangent.set_silent(tangent);
|
self.tangent.set_silent(tangent);
|
||||||
|
|
||||||
|
// clear the realization request flag
|
||||||
|
self.needs_realization.set(false);
|
||||||
},
|
},
|
||||||
Err(message) => {
|
Err(message) => {
|
||||||
// report the realization status. the `Err(message)` we're
|
// report the realization status. the `Err(message)` we're
|
||||||
|
@ -826,10 +849,10 @@ impl Assembly {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// bring the configuration back onto the solution variety. this also
|
// request a realization to bring the configuration back onto the
|
||||||
// gets the elements' column indices and the saved tangent space back in
|
// solution variety. this also gets the elements' column indices and the
|
||||||
// sync
|
// saved tangent space back in sync
|
||||||
self.realize();
|
self.needs_realization.set(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue