Keep large STEP assemblies responsive during 3D navigation (#1762)
Thanks @crono2250.
This commit is contained in:
1 parent
da65b4fc8c
commit
e2667b749d
6 files changed
+516
-78
No files matched your search
@@ -0,0 +1,64 @@
|
||||
//! Model-only browser queries, reused while navigating. Resolving a placement walks the
|
||||
//! definition's bodies; doing that for every offscreen row and folder made large imports
|
||||
//! quadratic on every frame. Keep the document and evaluated state alive with the index so
|
||||
//! neither a new document nor a later allocation can accidentally reuse its answers.
|
||||
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::sync::Arc;
|
||||
|
||||
use solidcraft_engine::Session;
|
||||
use solidcraft_engine::doc::{Document, FeatureKind, Mat, ModelState};
|
||||
use solidcraft_engine::occurrences::OccurrencePlacement;
|
||||
|
||||
pub(super) struct Model {
|
||||
doc: Arc<Document>,
|
||||
state: Arc<ModelState>,
|
||||
pending_moves: BTreeMap<u64, Mat>,
|
||||
pub bodies: HashMap<u64, Vec<usize>>,
|
||||
pub sketches: HashMap<u64, Vec<usize>>,
|
||||
pub planes: HashMap<u64, Vec<usize>>,
|
||||
pub children: HashMap<u64, Vec<u64>>,
|
||||
placements: HashMap<Vec<u64>, Option<Arc<OccurrencePlacement>>>,
|
||||
}
|
||||
|
||||
impl Model {
|
||||
pub fn new(session: &Session) -> Self {
|
||||
let state = session.model.state();
|
||||
let mut bodies: HashMap<u64, Vec<usize>> = HashMap::new();
|
||||
for (i, body) in state.bodies.iter().enumerate() {
|
||||
bodies.entry(session.doc.model_body_component(body)).or_default().push(i);
|
||||
}
|
||||
let mut sketches: HashMap<u64, Vec<usize>> = HashMap::new();
|
||||
let mut planes: HashMap<u64, Vec<usize>> = HashMap::new();
|
||||
for (i, feature) in session.doc.features.iter().enumerate() {
|
||||
let index = match feature.kind {
|
||||
FeatureKind::Sketch { .. } => &mut sketches,
|
||||
FeatureKind::ConstructionPlane { .. } => &mut planes,
|
||||
_ => continue,
|
||||
};
|
||||
index.entry(feature.component).or_default().push(i);
|
||||
}
|
||||
let mut children: HashMap<u64, Vec<u64>> = HashMap::new();
|
||||
for occurrence in &session.doc.occurrences {
|
||||
children.entry(occurrence.parent).or_default().push(occurrence.id);
|
||||
}
|
||||
Self {
|
||||
doc: session.doc.clone(),
|
||||
state,
|
||||
pending_moves: session.pending_moves.clone(),
|
||||
bodies,
|
||||
sketches,
|
||||
planes,
|
||||
children,
|
||||
placements: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn matches(&self, session: &Session) -> bool {
|
||||
Arc::ptr_eq(&self.doc, &session.doc) && Arc::ptr_eq(&self.state, &session.model.state()) && self.pending_moves == session.pending_moves
|
||||
}
|
||||
|
||||
pub fn placement(&mut self, session: &Session, path: &[u64]) -> Option<Arc<OccurrencePlacement>> {
|
||||
self.placements.entry(path.to_vec()).or_insert_with(|| session.occurrence_placement(path).ok().map(Arc::new)).clone()
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user