feat(arraypath): start the array from the path end nearest the pick
The travel direction of a path array now follows where the user clicks to select the path: the array starts from the nearest end, so clicking near either end picks the direction. A stored arc is always CCW regardless of how it was drawn, so without this the array could run opposite to expectation. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
cf6dd174fc
commit
75168145b3
1 changed files with 24 additions and 3 deletions
|
|
@ -493,6 +493,11 @@ pub struct ArrayPathCommand {
|
||||||
all_entities: Vec<EntityType>,
|
all_entities: Vec<EntityType>,
|
||||||
step: PathStep,
|
step: PathStep,
|
||||||
default_count: u32,
|
default_count: u32,
|
||||||
|
/// Where the user clicked to select the path. The array starts from the
|
||||||
|
/// path end nearest this point, so clicking near either end picks the
|
||||||
|
/// travel direction (a stored arc is always CCW regardless of how it was
|
||||||
|
/// drawn, so without this the array could run opposite to expectation).
|
||||||
|
pick_pt: Vec3,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ArrayPathCommand {
|
impl ArrayPathCommand {
|
||||||
|
|
@ -507,9 +512,24 @@ impl ArrayPathCommand {
|
||||||
all_entities,
|
all_entities,
|
||||||
step: PathStep::SelectPath,
|
step: PathStep::SelectPath,
|
||||||
default_count: defaults::get_array_path_count() as u32,
|
default_count: defaults::get_array_path_count() as u32,
|
||||||
|
pick_pt: Vec3::ZERO,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sample the path and orient the points so index 0 is the end nearest the
|
||||||
|
/// pick point, giving the user control over the array's travel direction.
|
||||||
|
fn oriented_samples(&self, entity: &EntityType, count: usize) -> Vec<Vec3> {
|
||||||
|
let mut pts = Self::sample_path(entity, count);
|
||||||
|
if pts.len() >= 2 {
|
||||||
|
let d_first = self.pick_pt.distance_squared(pts[0]);
|
||||||
|
let d_last = self.pick_pt.distance_squared(pts[pts.len() - 1]);
|
||||||
|
if d_last < d_first {
|
||||||
|
pts.reverse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pts
|
||||||
|
}
|
||||||
|
|
||||||
/// Sample `count` evenly-spaced points along `entity`.
|
/// Sample `count` evenly-spaced points along `entity`.
|
||||||
fn sample_path(entity: &EntityType, count: usize) -> Vec<Vec3> {
|
fn sample_path(entity: &EntityType, count: usize) -> Vec<Vec3> {
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
|
|
@ -688,7 +708,7 @@ impl CadCommand for ArrayPathCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_entity_pick(&mut self, handle: Handle, _pt: Vec3) -> CmdResult {
|
fn on_entity_pick(&mut self, handle: Handle, pt: Vec3) -> CmdResult {
|
||||||
if handle.is_null() || self.handles.contains(&handle) {
|
if handle.is_null() || self.handles.contains(&handle) {
|
||||||
return CmdResult::NeedPoint;
|
return CmdResult::NeedPoint;
|
||||||
}
|
}
|
||||||
|
|
@ -698,6 +718,7 @@ impl CadCommand for ArrayPathCommand {
|
||||||
.find(|e| e.common().handle == handle)
|
.find(|e| e.common().handle == handle)
|
||||||
.cloned()
|
.cloned()
|
||||||
{
|
{
|
||||||
|
self.pick_pt = pt;
|
||||||
self.step = PathStep::Count {
|
self.step = PathStep::Count {
|
||||||
path_entity: entity,
|
path_entity: entity,
|
||||||
};
|
};
|
||||||
|
|
@ -743,7 +764,7 @@ impl CadCommand for ArrayPathCommand {
|
||||||
self.default_count = v;
|
self.default_count = v;
|
||||||
v
|
v
|
||||||
};
|
};
|
||||||
let pts = Self::sample_path(path_entity, count as usize);
|
let pts = self.oriented_samples(path_entity, count as usize);
|
||||||
let transforms = Self::build_transforms(&pts);
|
let transforms = Self::build_transforms(&pts);
|
||||||
if transforms.is_empty() {
|
if transforms.is_empty() {
|
||||||
return Some(CmdResult::Cancel);
|
return Some(CmdResult::Cancel);
|
||||||
|
|
@ -755,7 +776,7 @@ impl CadCommand for ArrayPathCommand {
|
||||||
let PathStep::Count { path_entity } = &self.step else {
|
let PathStep::Count { path_entity } = &self.step else {
|
||||||
return vec![];
|
return vec![];
|
||||||
};
|
};
|
||||||
let pts = Self::sample_path(path_entity, self.default_count as usize);
|
let pts = self.oriented_samples(path_entity, self.default_count as usize);
|
||||||
let transforms = Self::build_transforms(&pts);
|
let transforms = Self::build_transforms(&pts);
|
||||||
transforms
|
transforms
|
||||||
.iter()
|
.iter()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue