forked from 1b-agent/opencadstudio-upstream
fix: resolve annotation pull request findings
This commit is contained in:
1 parent
293d0796fb
commit
6c0badbdc8
10 files changed
+407
-425
No files matched your search
@@ -39,33 +39,18 @@ impl DimBreakCommand {
|
||||
}
|
||||
}
|
||||
|
||||
fn marker(layer: String, primary: Handle) -> CmdResult {
|
||||
use acadrust::entities::XLine;
|
||||
let mut marker = XLine::default();
|
||||
marker.common.layer = layer;
|
||||
CmdResult::ReplaceEntity(primary, vec![EntityType::XLine(marker)])
|
||||
}
|
||||
|
||||
fn handles(handles: &[Handle]) -> String {
|
||||
handles
|
||||
.iter()
|
||||
.map(|handle| handle.value().to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(";")
|
||||
}
|
||||
|
||||
fn automatic(handles: &[Handle]) -> CmdResult {
|
||||
Self::marker(
|
||||
format!("__DIMBREAK_AUTO__{}", Self::handles(handles)),
|
||||
handles[0],
|
||||
)
|
||||
CmdResult::EditDimensionBreak {
|
||||
dimensions: handles.to_vec(),
|
||||
operation: crate::command::DimensionBreakOperation::Auto,
|
||||
}
|
||||
}
|
||||
|
||||
fn remove(handles: &[Handle]) -> CmdResult {
|
||||
Self::marker(
|
||||
format!("__DIMBREAK_REMOVE__{}", Self::handles(handles)),
|
||||
handles[0],
|
||||
)
|
||||
CmdResult::EditDimensionBreak {
|
||||
dimensions: handles.to_vec(),
|
||||
operation: crate::command::DimensionBreakOperation::Remove,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,14 +140,10 @@ impl CadCommand for DimBreakCommand {
|
||||
}
|
||||
CmdResult::NeedPoint
|
||||
}
|
||||
Step::PickCrossing(handles) => Self::marker(
|
||||
format!(
|
||||
"__DIMBREAK_OBJECT__{}|{}",
|
||||
Self::handles(handles),
|
||||
handle.value()
|
||||
),
|
||||
handles[0],
|
||||
),
|
||||
Step::PickCrossing(handles) => CmdResult::EditDimensionBreak {
|
||||
dimensions: handles.clone(),
|
||||
operation: crate::command::DimensionBreakOperation::Object(handle),
|
||||
},
|
||||
Step::ManualFirst(_) | Step::ManualSecond(_, _) => CmdResult::NeedPoint,
|
||||
}
|
||||
}
|
||||
@@ -194,19 +175,10 @@ impl CadCommand for DimBreakCommand {
|
||||
self.step = Step::ManualSecond(handles.clone(), point);
|
||||
CmdResult::NeedPoint
|
||||
}
|
||||
Step::ManualSecond(handles, first) => Self::marker(
|
||||
format!(
|
||||
"__DIMBREAK_MANUAL__{}|{:.15},{:.15},{:.15}|{:.15},{:.15},{:.15}",
|
||||
Self::handles(handles),
|
||||
first.x,
|
||||
first.y,
|
||||
first.z,
|
||||
point.x,
|
||||
point.y,
|
||||
point.z
|
||||
),
|
||||
handles[0],
|
||||
),
|
||||
Step::ManualSecond(handles, first) => CmdResult::EditDimensionBreak {
|
||||
dimensions: handles.clone(),
|
||||
operation: crate::command::DimensionBreakOperation::Manual(*first, point),
|
||||
},
|
||||
_ => CmdResult::NeedPoint,
|
||||
}
|
||||
}
|
||||
@@ -224,3 +196,21 @@ impl CadCommand for DimBreakCommand {
|
||||
}
|
||||
|
||||
inventory::submit!(crate::command::CommandRegistration { names: &["DIMBREAK"] });
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn automatic_break_returns_a_typed_edit() {
|
||||
let dimensions = vec![Handle::from(7), Handle::from(9)];
|
||||
let CmdResult::EditDimensionBreak {
|
||||
dimensions: actual,
|
||||
operation: crate::command::DimensionBreakOperation::Auto,
|
||||
} = DimBreakCommand::automatic(&dimensions)
|
||||
else {
|
||||
panic!("expected dimension break edit");
|
||||
};
|
||||
assert_eq!(actual, dimensions);
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
use acadrust::entities::Dimension;
|
||||
use acadrust::{EntityType, Handle};
|
||||
use glam::{DVec3, Vec3};
|
||||
use glam::DVec3;
|
||||
|
||||
use crate::command::{CadCommand, CmdOption, CmdResult, InputKind};
|
||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
@@ -43,16 +43,10 @@ impl DimJogLineCommand {
|
||||
}
|
||||
|
||||
fn result(handle: Handle, point: Option<DVec3>) -> CmdResult {
|
||||
use acadrust::entities::XLine;
|
||||
let mut marker = XLine::default();
|
||||
marker.common.layer = match point {
|
||||
Some(point) => format!(
|
||||
"__DIMJOG__{}|{:.15},{:.15},{:.15}",
|
||||
handle.value(), point.x, point.y, point.z
|
||||
),
|
||||
None => format!("__DIMJOG_REMOVE__{}", handle.value()),
|
||||
};
|
||||
CmdResult::ReplaceEntity(handle, vec![EntityType::XLine(marker)])
|
||||
CmdResult::EditDimensionJog {
|
||||
dimension: handle,
|
||||
point,
|
||||
}
|
||||
}
|
||||
|
||||
fn default_position(dimension: &Dimension) -> Option<DVec3> {
|
||||
@@ -75,29 +69,23 @@ impl DimJogLineCommand {
|
||||
}
|
||||
_ => return None,
|
||||
};
|
||||
let first = DVec3::new(first.x, first.y, first.z);
|
||||
let second = DVec3::new(second.x, second.y, second.z);
|
||||
let definition = DVec3::new(definition.x, definition.y, definition.z);
|
||||
let axis = axis.try_normalize().unwrap_or(DVec3::X);
|
||||
let perpendicular = DVec3::new(-axis.y, axis.x, 0.0);
|
||||
let offset = definition.dot(perpendicular);
|
||||
let first_on_line = first + perpendicular * (offset - first.dot(perpendicular));
|
||||
let second_on_line = second + perpendicular * (offset - second.dot(perpendicular));
|
||||
let midpoint = (first_on_line + second_on_line) * 0.5;
|
||||
|
||||
let text = dimension.base().text_middle_point;
|
||||
let text = DVec3::new(text.x, text.y, text.z);
|
||||
let line = second_on_line - first_on_line;
|
||||
let length_squared = line.length_squared();
|
||||
if length_squared <= 1.0e-18 {
|
||||
return Some(midpoint);
|
||||
}
|
||||
let parameter = (text - first_on_line).dot(line) / length_squared;
|
||||
if text.is_finite() && (0.0..=1.0).contains(¶meter) {
|
||||
Some((first_on_line + text) * 0.5)
|
||||
let base = dimension.base();
|
||||
let text = base.text_middle_point;
|
||||
let normal = base.normal;
|
||||
let text = if base.text_user_positioned {
|
||||
[text.x, text.y, text.z]
|
||||
} else {
|
||||
Some(midpoint)
|
||||
}
|
||||
[f64::NAN; 3]
|
||||
};
|
||||
cadkernel::space::default_dimension_jog_position(
|
||||
[first.x, first.y, first.z],
|
||||
[second.x, second.y, second.z],
|
||||
[definition.x, definition.y, definition.z],
|
||||
axis.to_array(),
|
||||
[normal.x, normal.y, normal.z],
|
||||
text,
|
||||
)
|
||||
.map(DVec3::from_array)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,34 +186,37 @@ impl CadCommand for DimJogLineCommand {
|
||||
if !matches!(self.step, Step::PickJogPos { .. }) {
|
||||
return None;
|
||||
}
|
||||
let axis = self
|
||||
.dimension
|
||||
.as_ref()
|
||||
.and_then(|dimension| match dimension {
|
||||
Dimension::Linear(value) => {
|
||||
Some(Vec3::new(value.rotation.cos() as f32, value.rotation.sin() as f32, 0.0))
|
||||
}
|
||||
Dimension::Aligned(value) => Some(Vec3::new(
|
||||
(value.second_point.x - value.first_point.x) as f32,
|
||||
(value.second_point.y - value.first_point.y) as f32,
|
||||
0.0,
|
||||
)),
|
||||
_ => None,
|
||||
})
|
||||
.and_then(Vec3::try_normalize)
|
||||
.unwrap_or(Vec3::X);
|
||||
let perpendicular = Vec3::new(-axis.y, axis.x, 0.0);
|
||||
let center = point.as_vec3();
|
||||
let size = 0.3;
|
||||
let points = vec![
|
||||
center - axis * size,
|
||||
center - axis * size * 0.25 + perpendicular * size,
|
||||
center + axis * size * 0.25 - perpendicular * size,
|
||||
center + axis * size,
|
||||
];
|
||||
let dimension = self.dimension.as_ref()?;
|
||||
let (segment, normal) = match dimension {
|
||||
Dimension::Linear(value) => {
|
||||
let axis = DVec3::new(value.rotation.cos(), value.rotation.sin(), 0.0);
|
||||
(
|
||||
[(point - axis).to_array(), (point + axis).to_array()],
|
||||
[value.base.normal.x, value.base.normal.y, value.base.normal.z],
|
||||
)
|
||||
}
|
||||
Dimension::Aligned(value) => (
|
||||
[
|
||||
[value.first_point.x, value.first_point.y, value.first_point.z],
|
||||
[value.second_point.x, value.second_point.y, value.second_point.z],
|
||||
],
|
||||
[value.base.normal.x, value.base.normal.y, value.base.normal.z],
|
||||
),
|
||||
_ => return None,
|
||||
};
|
||||
let points = cadkernel::space::dimension_jog_points(
|
||||
segment,
|
||||
point.to_array(),
|
||||
normal,
|
||||
0.3,
|
||||
std::f64::consts::FRAC_PI_2,
|
||||
)?;
|
||||
let mut preview = WireModel::default();
|
||||
preview.name = "dimjog_preview".into();
|
||||
preview.points = points.into_iter().map(|point| point.to_array()).collect();
|
||||
preview.points = points
|
||||
.into_iter()
|
||||
.map(|point| point.map(|value| value as f32))
|
||||
.collect();
|
||||
preview.color = WireModel::CYAN;
|
||||
preview.line_weight_px = 1.2;
|
||||
Some(preview)
|
||||
@@ -233,3 +224,22 @@ impl CadCommand for DimJogLineCommand {
|
||||
}
|
||||
|
||||
inventory::submit!(crate::command::CommandRegistration { names: &["DIMJOGLINE"] });
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn jog_result_keeps_the_selected_point() {
|
||||
let point = DVec3::new(1.0, 2.0, 3.0);
|
||||
let CmdResult::EditDimensionJog {
|
||||
dimension,
|
||||
point: actual,
|
||||
} = DimJogLineCommand::result(Handle::from(7), Some(point))
|
||||
else {
|
||||
panic!("expected dimension jog edit");
|
||||
};
|
||||
assert_eq!(dimension, Handle::from(7));
|
||||
assert_eq!(actual, Some(point));
|
||||
}
|
||||
}
|
||||
@@ -164,7 +164,7 @@ impl CadCommand for DimSpaceCommand {
|
||||
if let Step::EnterSpacing { base, others } = &self.step {
|
||||
let token = text.trim();
|
||||
let spacing = if matches!(token.to_ascii_uppercase().as_str(), "A" | "AUTO") {
|
||||
"AUTO".to_string()
|
||||
None
|
||||
} else {
|
||||
let Ok(value) = token.parse::<f64>() else {
|
||||
return Some(CmdResult::ReportError(
|
||||
@@ -176,24 +176,13 @@ impl CadCommand for DimSpaceCommand {
|
||||
t!("DIMSPACE: spacing value cannot be negative.").into_owned(),
|
||||
));
|
||||
}
|
||||
value.to_string()
|
||||
Some(value)
|
||||
};
|
||||
let b = *base;
|
||||
let o = others.clone();
|
||||
// Emit sentinel for commands.rs to handle
|
||||
use acadrust::entities::XLine;
|
||||
let mut xl = XLine::default();
|
||||
let handles_str: Vec<String> = o.iter().map(|h| h.value().to_string()).collect();
|
||||
xl.common.layer = format!(
|
||||
"__DIMSPACE__{},{},{}",
|
||||
b.value(),
|
||||
handles_str.join(";"),
|
||||
spacing
|
||||
);
|
||||
return Some(CmdResult::ReplaceEntity(
|
||||
b,
|
||||
vec![acadrust::EntityType::XLine(xl)],
|
||||
));
|
||||
return Some(CmdResult::SpaceDimensions {
|
||||
base: *base,
|
||||
others: others.clone(),
|
||||
spacing,
|
||||
});
|
||||
}
|
||||
None
|
||||
}
|
||||
@@ -211,7 +200,31 @@ impl CadCommand for DimSpaceCommand {
|
||||
CmdResult::Cancel
|
||||
}
|
||||
}
|
||||
inventory::submit!(crate::command::CommandRegistration { names: &["DIMSPACE", "DSPACE"] });
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
// ── Autocomplete registry ─────────────────────────────────
|
||||
inventory::submit!(crate::command::CommandRegistration { names: &["DIMSPACE", "DSPACE"] }); // DimSpaceCommand
|
||||
#[test]
|
||||
fn auto_spacing_returns_a_typed_edit() {
|
||||
let mut command = DimSpaceCommand {
|
||||
step: Step::EnterSpacing {
|
||||
base: Handle::from(2),
|
||||
others: vec![Handle::from(3)],
|
||||
},
|
||||
picked_entity: None,
|
||||
};
|
||||
let Some(CmdResult::SpaceDimensions {
|
||||
base,
|
||||
others,
|
||||
spacing,
|
||||
}) = command.on_text_input("Auto")
|
||||
else {
|
||||
panic!("expected dimension spacing edit");
|
||||
};
|
||||
assert_eq!(base, Handle::from(2));
|
||||
assert_eq!(others, vec![Handle::from(3)]);
|
||||
assert_eq!(spacing, None);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user