forked from 1b-agent/opencadstudio-upstream
Make a large selection scale with the drawing
Selecting a whole drawing was unusable on a 186 468-entity file. Four costs scaled with the selection where they did not have to. Every selected handle triggered a walk of the entire document to find LEADERs pointing at it. On the file this came from, selecting 471 583 entities in a 585 786-entity drawing did not finish inside eight minutes. A reverse index built once per geometry epoch answers the same question; a test asserts it returns exactly what the walk returned, including the case of two leaders on one annotation. Group expansion asked the selection about every group: for each selected handle it scanned each group's own member list. Asking each group once whether it holds anything selected turns that around. Selecting and deselecting went one entity at a time, and `deselect_entity` rebuilt the ordered list with a `retain` per handle, so removing N of M walked the order list N times. Both now take a slice. Grips were built for every selected entity. AutoCAD stops at GRIPOBJLIMIT, and the DWG header does not carry the variable, so its default of 100 stands in for it. The remaining two commits are measurement: `select-commit` reports the phases of a selection separately, which is what showed the bulk paths had been added to the press-drag branch while a click-move-click window goes through a different one entirely.
This commit is contained in:
1 parent
56e09cd3f5
commit
d02ce08349
5 files changed
+424
-42
No files matched your search
@@ -1877,6 +1877,13 @@ pub struct Scene {
|
||||
entity_block_map_cache: RefCell<Option<(u64, HashMap<Handle, Handle>)>>,
|
||||
/// Candidate handles per block, in document order and keyed by geometry epoch.
|
||||
block_members_cache: RefCell<Option<BlockMembers>>,
|
||||
/// Annotation handle -> the LEADERs that point at it, resolved once per
|
||||
/// `geometry_epoch`.
|
||||
///
|
||||
/// Selecting an entity has to pull in a LEADER whose annotation it is, and
|
||||
/// that used to be answered by walking the whole document — per selected
|
||||
/// handle. Selecting N entities cost N document walks.
|
||||
leaders_by_annotation_cache: RefCell<Option<(u64, HashMap<Handle, Vec<Handle>>)>>,
|
||||
/// Insert/Viewport/Block/BlockEnd handles omitted by the spatial index.
|
||||
unindexable_cache: RefCell<Option<(u64, Vec<Handle>)>>,
|
||||
/// `(epoch, layout block, present type names, list exposed to the UI)`.
|
||||
@@ -2128,6 +2135,7 @@ impl Scene {
|
||||
model_extents_cache: RefCell::new(None),
|
||||
entity_block_map_cache: RefCell::new(None),
|
||||
block_members_cache: RefCell::new(None),
|
||||
leaders_by_annotation_cache: RefCell::new(None),
|
||||
unindexable_cache: RefCell::new(None),
|
||||
layout_type_names_cache: RefCell::new(None),
|
||||
dependency_index_cache: RefCell::new(None),
|
||||
@@ -10797,6 +10805,8 @@ mod journal_tests {
|
||||
assert_eq!(folded.len(), before.len() + 1);
|
||||
}
|
||||
|
||||
// Differential oracle: the incrementally-patched entity index must always
|
||||
// equal a from-scratch rebuild after any add / move / erase.
|
||||
#[test]
|
||||
fn block_member_index_matches_the_full_scan() {
|
||||
use acadrust::entities::Line;
|
||||
|
||||
Reference in new issue
Block a user