Validate viewport object picks and cover angular arc acquisition

This commit is contained in:
Christopher Overbeck committed 2026-09-15 14:53:29 -05:00
1 parent 2ee3782850
commit 3274d6d0fd
3 files changed
+53 -1

No files matched your search

+2
View File
@@ -11,6 +11,8 @@ Snapping and object picking share viewport draw order, visibility, and clipping
rules. Object picking uses the resident interaction index and applies block rules. Object picking uses the resident interaction index and applies block
instance transforms. Nonuniformly transformed circles and circular arcs are instance transforms. Nonuniformly transformed circles and circular arcs are
declined as radial object picks because their displayed geometry is elliptical. declined as radial object picks because their displayed geometry is elliptical.
Array inserts without an addressable instance index are also declined; resolved
block geometry must remain within the original pick aperture.
## Input and measurement rules ## Input and measurement rules
+45 -1
View File
@@ -239,11 +239,20 @@ fn viewport_dimension_linear_aligned_and_radial_object_picks() {
#[test] #[test]
fn viewport_dimension_angular_preserves_angle_without_length_factor() { fn viewport_dimension_angular_preserves_angle_without_length_factor() {
let (mut app, line, frame) = fixture(); let (mut app, line, frame) = fixture();
let i = app.active_tab;
app.tabs[i].scene.set_current_layout("Model".into());
let vertical = app.tabs[i]
.scene
.add_entity(EntityType::Line(Line::from_points(
Vector3::ZERO,
Vector3::new(0.0, 100.0, 0.0),
)));
app.tabs[i].scene.set_current_layout("Dimensions".into());
let _ = app.dispatch_command("DIMANGULAR"); let _ = app.dispatch_command("DIMANGULAR");
let _ = app.feed_command(StepInput::Enter); let _ = app.feed_command(StepInput::Enter);
point(&mut app, frame, line, DVec3::ZERO); point(&mut app, frame, line, DVec3::ZERO);
point(&mut app, frame, line, DVec3::X * 100.0); point(&mut app, frame, line, DVec3::X * 100.0);
point(&mut app, frame, line, DVec3::Y * 100.0); point(&mut app, frame, vertical, DVec3::Y * 100.0);
let _ = app.feed_command(StepInput::Point(DVec3::new(70.0, 70.0, 0.0))); let _ = app.feed_command(StepInput::Point(DVec3::new(70.0, 70.0, 0.0)));
let doc = &app.tabs[app.active_tab].scene.document; let doc = &app.tabs[app.active_tab].scene.document;
assert!((dimension(doc).measurement() - 90.0).abs() < 1e-5); assert!((dimension(doc).measurement() - 90.0).abs() < 1e-5);
@@ -377,3 +386,38 @@ fn viewport_dimension_exploded_commit_uses_compensated_text_and_undo() {
.entities() .entities()
.any(|e| matches!(e, EntityType::Text(_) | EntityType::MText(_)))); .any(|e| matches!(e, EntityType::Text(_) | EntityType::MText(_))));
} }
#[test]
fn viewport_dimension_angular_object_picks_measure_arc_features() {
use acadrust::entities::{Arc, LwPolyline};
use acadrust::types::Vector2;
for bulged in [false, true] {
let (mut app, _, frame) = fixture();
let i = app.active_tab;
app.tabs[i].scene.set_current_layout("Model".into());
let entity = if bulged {
let mut poly =
LwPolyline::from_points(vec![Vector2::new(100.0, 200.0), Vector2::new(0.0, 300.0)]);
poly.vertices[0].bulge = (std::f64::consts::PI / 8.0).tan();
EntityType::LwPolyline(poly)
} else {
let mut arc = Arc::new();
arc.center = Vector3::new(0.0, 200.0, 0.0);
arc.radius = 100.0;
arc.start_angle = 0.0;
arc.end_angle = std::f64::consts::FRAC_PI_2;
EntityType::Arc(arc)
};
app.tabs[i].scene.add_entity(entity);
app.tabs[i].scene.set_current_layout("Dimensions".into());
let _ = app.dispatch_command("DIMANGULAR");
let model = DVec3::new(100.0 / 2.0_f64.sqrt(), 200.0 + 100.0 / 2.0_f64.sqrt(), 0.0);
let result = app
.try_dimension_viewport_entity_pick(i, frame.model_to_paper(model), 0.5)
.unwrap();
let _ = app.apply_cmd_result(result);
assert_eq!(app.accepted_snaps().len(), 3);
let _ = app.feed_command(StepInput::Point(DVec3::new(65.0, 85.0, 0.0)));
assert!((displayed(&app.tabs[i].scene.document) - 90.0).abs() < 1e-5);
}
}
+6
View File
@@ -84,6 +84,9 @@ impl Scene {
continue; continue;
}; };
if !planar_pick_distance(&entity, model_point).is_some_and(|d| d <= aperture_model) {
continue;
}
let mut paper_entity = entity; let mut paper_entity = entity;
crate::scene::view::dispatch::apply_transform( crate::scene::view::dispatch::apply_transform(
&mut paper_entity, &mut paper_entity,
@@ -212,6 +215,9 @@ impl Scene {
let EntityType::Insert(insert) = &insert_entity else { let EntityType::Insert(insert) = &insert_entity else {
return None; return None;
}; };
if insert.row_count > 1 || insert.column_count > 1 {
return None;
}
let insert_handle = insert.common.handle; let insert_handle = insert.common.handle;
let local = crate::scene::render_graph::insert_transform(&self.document, insert); let local = crate::scene::render_graph::insert_transform(&self.document, insert);
let combined = local.then(&outer); let combined = local.then(&outer);