Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions crates/solidcore/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ readme = "README.md"
keywords = ["cad", "brep", "nurbs", "geometry", "solid-modeling"]
categories = ["graphics", "mathematics", "science"]

[features]
# Kernels start with the curve cache memo off (`Kernel::memoize_curve_caches`), to
# run difftest and the tests in both positions. Results never depend on it.
curve-memo-off = []

[dependencies]
thiserror.workspace = true

Expand Down
1 change: 1 addition & 0 deletions crates/solidcore/src/boolean/merge/p4/kernel_adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ fn cache_kernel(k: &Kernel, context: &Context) -> Kernel {
fillet_point_step: core::cell::Cell::new(k.fillet_point_step.get()),
upstream_ub_passed: Vec::new(),
cone_parallel_midpoint_test: core::cell::Cell::new(k.cone_parallel_midpoint_test.get()),
memoize_curve_caches: k.memoize_curve_caches,
}
}

Expand Down
38 changes: 37 additions & 1 deletion crates/solidcore/src/curve/curve/p2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@
//! (`SM_NO_CONSTRUCTION`, `SM_NO_DESTRUCTION`) and the debug cache counter are
//! not modelled; [`notify`] is the `Notify` override for callers that keep the
//! curve's [`AObject`] state.
//! - **Cache memo.** A [`Curve`] carries a memo of its curve cache (`CurveMemo`, see
//! `curve.curve_p5`), which upstream keeps in `SmCacheMgr`. `Clone` and the
//! evaluation copies share it; every `&mut` edit of the geometry (`kind_mut` and the
//! editing methods) starts an empty one.
//! - **Arguments.** Out-params become return values; `SmContext` arguments only
//! choose where upstream allocates and are dropped, as are arguments upstream
//! marks `NotUsed` (`EvaluateSTEP`'s zone tolerance, `sm_TestStep`'s current
Expand Down Expand Up @@ -163,6 +167,7 @@ use crate::curve::composite_curve::CompositeCurve;
use crate::curve::conic::Conic;
use crate::curve::crv_in_volume::CrvInVolume;
use crate::curve::crv_on_surf::CrvOnSurf;
use crate::curve::curve::p5::CurveMemo;
use crate::curve::ellipse::Ellipse;
use crate::curve::hermite_curve::HermiteCurve;
use crate::curve::hyperbola::Hyperbola;
Expand Down Expand Up @@ -578,16 +583,20 @@ pub struct Curve {
/// the object itself), issued by the context of the first notification that names
/// it ([`IdentitySlot`]).
notify_identity: IdentitySlot,
/// Not upstream: the memo of the curve's cache ([`CurveMemo`]), shared by clones
/// and emptied by every edit of the geometry.
memo: CurveMemo,
}

/// The copy constructor: copies the geometry, resets the owner (and the identity: a
/// copy is another object).
/// copy is another object). The copy shares the curve cache memo (same geometry).
impl Clone for Curve {
fn clone(&self) -> Self {
Self {
kind: self.kind.clone(),
owner: None,
notify_identity: IdentitySlot::new(),
memo: self.memo.share(),
}
}
}
Expand Down Expand Up @@ -621,6 +630,7 @@ impl Curve {
owner: self.owner,
// an evaluation snapshot is never notified under the original's identity
notify_identity: IdentitySlot::new(),
memo: self.memo.share(),
}
}
}
Expand Down Expand Up @@ -768,6 +778,7 @@ impl Curve {
kind,
owner: self.owner,
notify_identity: IdentitySlot::new(),
memo: self.memo.share(),
})
}

Expand All @@ -779,9 +790,27 @@ impl Curve {
kind,
owner: None,
notify_identity: IdentitySlot::new(),
memo: CurveMemo::new(),
}
}

/// A copy (as `Clone`) with an empty curve cache memo of its own: the curve a
/// cache keeps of its own, so a memo never holds itself.
#[must_use]
pub(crate) fn clone_detached(&self) -> Self {
Self {
kind: self.kind.clone(),
owner: None,
notify_identity: IdentitySlot::new(),
memo: CurveMemo::new(),
}
}

/// The curve cache memo (see [`CurveMemo`]).
pub(crate) const fn memo(&self) -> &CurveMemo {
&self.memo
}

/// The key this curve object is notified under, once a context has issued it one
/// (the kernel issues it; there is no setter).
#[must_use]
Expand All @@ -803,6 +832,8 @@ impl Curve {

/// The concrete kind, mutable.
pub fn kind_mut(&mut self) -> &mut CurveKind {
// an edit makes another curve value: start an empty memo
self.memo = CurveMemo::new();
&mut self.kind
}

Expand Down Expand Up @@ -1523,6 +1554,7 @@ impl Curve {
/// `SM_ERR` for kinds without the conversion; those of
/// [`BSplineCurve::convert_to_2d`].
pub fn convert_to_2d(&mut self, k: &Kernel) -> Result<()> {
self.memo = CurveMemo::new();
match &mut self.kind {
CurveKind::BSpline(c) => c.convert_to_2d(),
CurveKind::Hyperbola(c) => c.base.convert_to_2d(),
Expand All @@ -1547,6 +1579,7 @@ impl Curve {
/// `SM_ERR` for kinds without the edit; those of
/// [`BSplineCurve::edit_parameterization`].
pub fn edit_parameterization(&mut self, k: &Kernel, new_param: &Extent1d) -> Result<()> {
self.memo = CurveMemo::new();
match &mut self.kind {
CurveKind::BSpline(c) => c.edit_parameterization(new_param),
CurveKind::Hyperbola(c) => c.base.edit_parameterization(new_param),
Expand Down Expand Up @@ -1576,6 +1609,7 @@ impl Curve {
old_interval: &Extent1d,
) -> Result<Extent1d> {
let owner = self.owner;
self.memo = CurveMemo::new();
match &mut self.kind {
CurveKind::BSpline(c) => c.reverse_parameterization(old_interval),
CurveKind::Hyperbola(c) => c.reverse_parameterization(old_interval, owner),
Expand Down Expand Up @@ -1616,6 +1650,7 @@ impl Curve {
scale: Option<Vec3>,
depth: usize,
) -> Result<()> {
self.memo = CurveMemo::new();
match &mut self.kind {
CurveKind::Composite(c) => c.transform_at_depth(k, rotate_n_move, scale, depth),
CurveKind::BSpline(c) => c.transform(rotate_n_move, scale),
Expand All @@ -1639,6 +1674,7 @@ impl Curve {
///
/// `SM_ERR` for kinds without the edit; those of [`BSplineCurve::trim`].
pub fn trim(&mut self, k: &Kernel, trim_interval: &mut Extent1d, mode: TrimMode) -> Result<()> {
self.memo = CurveMemo::new();
match &mut self.kind {
CurveKind::BSpline(c) => c.trim(k, trim_interval, mode),
CurveKind::Hyperbola(c) => c.base.trim(k, trim_interval, mode),
Expand Down
Loading
Loading