forked from 1b-agent/opencadstudio-upstream
fix(blocks): show directional Flip grip arrows
Use the existing triangular grip marker in Test Block and saved drawing references. Point it across the reflection line, transform it with the INSERT, and reverse the arrow when the native Flip state changes. Validate arrow shape and both directions through the existing mouse-click, undo/redo and reopen regression in both contexts.
This commit is contained in:
1 parent
1ee432ac64
commit
94940ad77c
3 files changed
+43
-12
No files matched your search
+12
-12
@@ -242,12 +242,12 @@ impl OpenCADStudio {
|
||||
id: TEST_GRIP_START + index,
|
||||
world,
|
||||
is_midpoint: false,
|
||||
shape: if p.flip {
|
||||
crate::scene::model::object::GripShape::Square
|
||||
} else {
|
||||
crate::scene::model::object::GripShape::Triangle
|
||||
},
|
||||
dir: None,
|
||||
shape: crate::scene::model::object::GripShape::Triangle,
|
||||
dir: actions::grip_direction(&p, value).and_then(|direction| {
|
||||
(actions::v(transform.apply(actions::native(direction)))
|
||||
- actions::v(transform.apply(codec::types::Vector3::ZERO)))
|
||||
.try_normalize()
|
||||
}),
|
||||
axis: None,
|
||||
});
|
||||
}
|
||||
@@ -336,12 +336,12 @@ impl OpenCADStudio {
|
||||
id: TEST_GRIP_START + index,
|
||||
world,
|
||||
is_midpoint: false,
|
||||
shape: if p.flip {
|
||||
crate::scene::model::object::GripShape::Square
|
||||
} else {
|
||||
crate::scene::model::object::GripShape::Triangle
|
||||
},
|
||||
dir: None,
|
||||
shape: crate::scene::model::object::GripShape::Triangle,
|
||||
dir: actions::grip_direction(&p, value).and_then(|direction| {
|
||||
(actions::v(transform.apply(actions::native(direction)))
|
||||
- actions::v(transform.apply(codec::types::Vector3::ZERO)))
|
||||
.try_normalize()
|
||||
}),
|
||||
axis: None,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -270,12 +270,34 @@ fn block_actions_rotate_flip_mouse_grips_authoring_history_and_reopen() {
|
||||
app.tabs[i].scene.selected.insert(insert);
|
||||
app.refresh_properties();
|
||||
let depth = app.tabs[i].history.undo_stack.len();
|
||||
let flip_grip = app.tabs[i]
|
||||
.selected_grips
|
||||
.iter()
|
||||
.find(|g| {
|
||||
super::block_actions::is_test_grip(g.id) && g.world.distance(flip.reference) < 1e-5
|
||||
})
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
flip_grip.shape,
|
||||
crate::scene::model::object::GripShape::Triangle
|
||||
);
|
||||
assert!(flip_grip.dir.unwrap().distance(glam::DVec3::Y) < 1e-5);
|
||||
click(&mut app, flip.reference);
|
||||
assert!(
|
||||
app.tabs[i].active_cmd.is_none(),
|
||||
"Flip toggles immediately without point input"
|
||||
);
|
||||
check(&app, insert, -Vector3::UNIT_Y);
|
||||
app.tabs[i].scene.selected.insert(insert);
|
||||
app.refresh_properties();
|
||||
let flip_grip = app.tabs[i]
|
||||
.selected_grips
|
||||
.iter()
|
||||
.find(|g| {
|
||||
super::block_actions::is_test_grip(g.id) && g.world.distance(flip.reference) < 1e-5
|
||||
})
|
||||
.unwrap();
|
||||
assert!(flip_grip.dir.unwrap().distance(-glam::DVec3::Y) < 1e-5);
|
||||
assert_eq!(app.tabs[i].history.undo_stack.len(), depth + 1);
|
||||
app.undo_steps(1);
|
||||
check(&app, insert, Vector3::UNIT_Y);
|
||||
|
||||
@@ -172,6 +172,15 @@ pub(crate) fn grip_position(p: &Parameter, value: Value) -> DVec3 {
|
||||
}
|
||||
}
|
||||
|
||||
/// A Flip arrow points across its reflection line and reverses with its state.
|
||||
pub(crate) fn grip_direction(p: &Parameter, value: Value) -> Option<DVec3> {
|
||||
let Value::Flip(flipped) = value else {
|
||||
return None;
|
||||
};
|
||||
let across = DVec3::Z.cross(p.end - p.base).try_normalize()?;
|
||||
Some(if flipped { -across } else { across })
|
||||
}
|
||||
|
||||
pub(crate) fn parameters(doc: &CadDocument, definition: Handle, kind: Kind) -> Vec<Parameter> {
|
||||
let Ok(Some(graph)) = authoring::graph(doc, definition) else {
|
||||
return vec![];
|
||||
|
||||
Reference in new issue
Block a user