Remap pending vertex tangents through polyline edits and undo

This commit is contained in:
ramox81 committed 2026-09-11 11:51:54 +03:00
1 parent 499beb718f
commit dd9ef2f236
1 file changed
+35 -2
+35 -2
View File
@@ -61,6 +61,8 @@ pub struct PeditCommand {
mode: Mode,
undo_count: usize,
vertex_tangents: HashMap<usize, f64>,
pending_tangents: Option<HashMap<usize, f64>>,
tangent_history: Vec<HashMap<usize, f64>>,
mesh_smooth_type: acadrust::entities::polygon_mesh::SurfaceSmoothType,
mesh_smooth_density: (i16, i16),
mesh_vertex_default: isize,
@@ -92,6 +94,8 @@ impl PeditCommand {
mode: Mode::PickTarget,
undo_count: 0,
vertex_tangents: HashMap::default(),
pending_tangents: None,
tangent_history: Vec::new(),
mesh_smooth_type,
mesh_smooth_density: (
surface_u_density.clamp(2, 200),
@@ -147,6 +151,25 @@ impl PeditCommand {
}
}
fn mapped_tangents(&self, op: &PeditOp) -> Option<HashMap<usize, f64>> {
let count = self.vertex_count();
match op {
PeditOp::Reverse => Some(self.vertex_tangents.iter().filter_map(|(&index, &angle)|
(index < count).then_some((count.saturating_sub(index + 1), (angle + std::f64::consts::PI).rem_euclid(TAU)))).collect()),
PeditOp::EditVertex { index, insert: true, .. } => Some(self.vertex_tangents.iter().map(|(&old, &angle)|
(if old > *index { old + 1 } else { old }, angle)).collect()),
PeditOp::VertexRange { first, last, split } => Some(self.vertex_tangents.iter().filter_map(|(&index, &angle)| {
if *split {
if *first > 0 { (index <= *first).then_some((index, angle)) }
else { (index >= *last).then_some((index.saturating_sub(*last), angle)) }
} else if index > *first && index < *last { None }
else { Some((if index >= *last { index.saturating_sub(last.saturating_sub(*first + 1)) } else { index }, angle)) }
}).collect()),
PeditOp::Fit | PeditOp::FitWithTangents(_) | PeditOp::Decurve | PeditOp::Spline => Some(HashMap::default()),
_ => None,
}
}
fn vertex_width(&self, index: usize) -> f64 {
let entity = self.target.and_then(|handle| self.entities.get(&handle.value()));
match entity {
@@ -381,6 +404,8 @@ impl CadCommand for PeditCommand {
}
fn on_pedit_applied(&mut self) {
self.tangent_history.push(self.vertex_tangents.clone());
if let Some(mapped) = self.pending_tangents.take() { self.vertex_tangents = mapped; }
self.undo_count = self.undo_count.saturating_add(1);
self.multiple_history.push(self.pending_multiple.take().unwrap_or_else(|| self.multiple.clone()));
if let Some((m_direction, closed)) = self.pending_mesh_closed.take() {
@@ -398,6 +423,7 @@ impl CadCommand for PeditCommand {
fn on_text_input(&mut self, text: &str) -> Option<CmdResult> {
self.pending_mesh_closed = None;
self.pending_tangents = None;
let up = text.trim().to_uppercase();
let mesh_size = self.mesh_size();
let vertex_count = self.vertex_count();
@@ -485,7 +511,9 @@ impl CadCommand for PeditCommand {
"G" | "GO" => {
let (first, last, split) = ((*start).min(*end), (*start).max(*end), *split);
self.mode = Mode::PolyVertex(first);
return Some(CmdResult::PeditOp { handle: self.target?, op: PeditOp::VertexRange { first, last, split } });
let op = PeditOp::VertexRange { first, last, split };
self.pending_tangents = self.mapped_tangents(&op);
return Some(CmdResult::PeditOp { handle: self.target?, op });
}
_ => {}
}
@@ -615,6 +643,7 @@ impl CadCommand for PeditCommand {
"U" | "UNDO" if self.undo_count > 0 => {
self.undo_count -= 1;
self.mesh_closed_history.pop();
if let Some(tangents) = self.tangent_history.pop() { self.vertex_tangents = tangents; }
if let Some(previous) = self.multiple_history.pop() {
self.multiple = previous;
if !self.multiple.is_empty() { self.target = self.multiple.first().copied(); }
@@ -667,10 +696,12 @@ impl CadCommand for PeditCommand {
}
}
};
if let Some(CmdResult::PeditOp { op, .. }) = &result { self.pending_tangents = self.mapped_tangents(op); }
self.multiple_result(result)
}
fn on_point(&mut self, point: DVec3) -> CmdResult {
self.pending_tangents = None;
if let Mode::PolyTangent(index) = self.mode {
let Some(entity) = self.target.and_then(|handle| self.entities.get(&handle.value())) else { return CmdResult::NeedPoint; };
let (normal, elevation, location) = match entity {
@@ -690,7 +721,9 @@ impl CadCommand for PeditCommand {
let Some(handle) = self.target else { return CmdResult::Cancel; };
let insert = matches!(self.mode, Mode::PolyInsert(_));
self.mode = Mode::PolyVertex(index);
return CmdResult::PeditOp { handle, op: PeditOp::EditVertex { index, point, insert } };
let op = PeditOp::EditVertex { index, point, insert };
self.pending_tangents = self.mapped_tangents(&op);
return CmdResult::PeditOp { handle, op };
}
if let Mode::MeshVertexMove(index) = self.mode {
let Some(handle) = self.target else {