forked from 1b-agent/opencadstudio-upstream
cargo fmt
This commit is contained in:
1 parent
468cbde5e1
commit
ca07268c7c
204 files changed
+13997
-5525
No files matched your search
@@ -16,9 +16,18 @@ use crate::scene::wire_model::WireModel;
|
||||
|
||||
enum Step {
|
||||
Tag,
|
||||
Prompt { tag: String },
|
||||
Default { tag: String, prompt: String },
|
||||
Insertion { tag: String, prompt: String, default: String },
|
||||
Prompt {
|
||||
tag: String,
|
||||
},
|
||||
Default {
|
||||
tag: String,
|
||||
prompt: String,
|
||||
},
|
||||
Insertion {
|
||||
tag: String,
|
||||
prompt: String,
|
||||
default: String,
|
||||
},
|
||||
}
|
||||
|
||||
pub struct AttdefCommand {
|
||||
@@ -29,18 +38,25 @@ pub struct AttdefCommand {
|
||||
|
||||
impl AttdefCommand {
|
||||
pub fn new() -> Self {
|
||||
Self { step: Step::Tag, height: 0.2 }
|
||||
Self {
|
||||
step: Step::Tag,
|
||||
height: 0.2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CadCommand for AttdefCommand {
|
||||
fn name(&self) -> &'static str { "ATTDEF" }
|
||||
fn name(&self) -> &'static str {
|
||||
"ATTDEF"
|
||||
}
|
||||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.step {
|
||||
Step::Tag => "ATTDEF Enter attribute tag (no spaces):".into(),
|
||||
Step::Tag => "ATTDEF Enter attribute tag (no spaces):".into(),
|
||||
Step::Prompt { tag } => format!("ATTDEF Enter prompt for '{tag}' (Enter=use tag):"),
|
||||
Step::Default { tag, .. } => format!("ATTDEF Enter default value for '{tag}' (Enter=blank):"),
|
||||
Step::Default { tag, .. } => {
|
||||
format!("ATTDEF Enter default value for '{tag}' (Enter=blank):")
|
||||
}
|
||||
Step::Insertion { tag, .. } => format!("ATTDEF Specify insertion point for '{tag}':"),
|
||||
}
|
||||
}
|
||||
@@ -61,7 +77,11 @@ impl CadCommand for AttdefCommand {
|
||||
}
|
||||
Step::Prompt { tag } => {
|
||||
let tag = tag.clone();
|
||||
let prompt = if text.trim().is_empty() { tag.clone() } else { text.trim().to_string() };
|
||||
let prompt = if text.trim().is_empty() {
|
||||
tag.clone()
|
||||
} else {
|
||||
text.trim().to_string()
|
||||
};
|
||||
self.step = Step::Default { tag, prompt };
|
||||
Some(CmdResult::NeedPoint)
|
||||
}
|
||||
@@ -69,7 +89,11 @@ impl CadCommand for AttdefCommand {
|
||||
let tag = tag.clone();
|
||||
let prompt = prompt.clone();
|
||||
let default = text.trim().to_string();
|
||||
self.step = Step::Insertion { tag, prompt, default };
|
||||
self.step = Step::Insertion {
|
||||
tag,
|
||||
prompt,
|
||||
default,
|
||||
};
|
||||
Some(CmdResult::NeedPoint)
|
||||
}
|
||||
Step::Insertion { .. } => None,
|
||||
@@ -77,7 +101,12 @@ impl CadCommand for AttdefCommand {
|
||||
}
|
||||
|
||||
fn on_point(&mut self, pt: Vec3) -> CmdResult {
|
||||
if let Step::Insertion { tag, prompt, default } = &self.step {
|
||||
if let Step::Insertion {
|
||||
tag,
|
||||
prompt,
|
||||
default,
|
||||
} = &self.step
|
||||
{
|
||||
let mut attdef = AttributeDefinition {
|
||||
tag: tag.clone(),
|
||||
prompt: prompt.clone(),
|
||||
@@ -99,12 +128,19 @@ impl CadCommand for AttdefCommand {
|
||||
// Treat Enter as empty text input for prompt/default steps.
|
||||
Step::Prompt { tag } => {
|
||||
let tag = tag.clone();
|
||||
self.step = Step::Default { tag: tag.clone(), prompt: tag };
|
||||
self.step = Step::Default {
|
||||
tag: tag.clone(),
|
||||
prompt: tag,
|
||||
};
|
||||
CmdResult::NeedPoint
|
||||
}
|
||||
Step::Default { tag, prompt } => {
|
||||
let (tag, prompt) = (tag.clone(), prompt.clone());
|
||||
self.step = Step::Insertion { tag, prompt, default: String::new() };
|
||||
self.step = Step::Insertion {
|
||||
tag,
|
||||
prompt,
|
||||
default: String::new(),
|
||||
};
|
||||
CmdResult::NeedPoint
|
||||
}
|
||||
Step::Insertion { .. } => CmdResult::Cancel,
|
||||
@@ -120,9 +156,11 @@ impl CadCommand for AttdefCommand {
|
||||
Some(WireModel {
|
||||
name: "attdef_preview".into(),
|
||||
points: vec![
|
||||
[pt.x - d, pt.y, pt.z], [pt.x + d, pt.y, pt.z],
|
||||
[pt.x - d, pt.y, pt.z],
|
||||
[pt.x + d, pt.y, pt.z],
|
||||
[f32::NAN, 0.0, 0.0],
|
||||
[pt.x, pt.y, pt.z - d], [pt.x, pt.y, pt.z + d],
|
||||
[pt.x, pt.y, pt.z - d],
|
||||
[pt.x, pt.y, pt.z + d],
|
||||
],
|
||||
color: WireModel::CYAN,
|
||||
selected: false,
|
||||
|
||||
@@ -39,12 +39,14 @@ impl DonutCommand {
|
||||
}
|
||||
|
||||
impl CadCommand for DonutCommand {
|
||||
fn name(&self) -> &'static str { "DONUT" }
|
||||
fn name(&self) -> &'static str {
|
||||
"DONUT"
|
||||
}
|
||||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.state {
|
||||
DonutState::AskInner => "DONUT Specify inside diameter <0>:".into(),
|
||||
DonutState::AskOuter => "DONUT Specify outside diameter:".into(),
|
||||
DonutState::AskInner => "DONUT Specify inside diameter <0>:".into(),
|
||||
DonutState::AskOuter => "DONUT Specify outside diameter:".into(),
|
||||
DonutState::PlaceCenter => "DONUT Specify center of donut (Enter to exit):".into(),
|
||||
}
|
||||
}
|
||||
@@ -54,7 +56,12 @@ impl CadCommand for DonutCommand {
|
||||
}
|
||||
|
||||
fn on_text_input(&mut self, text: &str) -> Option<CmdResult> {
|
||||
let val: f64 = text.trim().replace(',', ".").parse().ok().filter(|&v: &f64| v >= 0.0)?;
|
||||
let val: f64 = text
|
||||
.trim()
|
||||
.replace(',', ".")
|
||||
.parse()
|
||||
.ok()
|
||||
.filter(|&v: &f64| v >= 0.0)?;
|
||||
match &self.state {
|
||||
DonutState::AskInner => {
|
||||
self.inner_r = val / 2.0;
|
||||
@@ -62,7 +69,9 @@ impl CadCommand for DonutCommand {
|
||||
Some(CmdResult::NeedPoint)
|
||||
}
|
||||
DonutState::AskOuter => {
|
||||
if val <= 0.0 { return None; }
|
||||
if val <= 0.0 {
|
||||
return None;
|
||||
}
|
||||
self.outer_r = val / 2.0;
|
||||
if self.inner_r > self.outer_r {
|
||||
std::mem::swap(&mut self.inner_r, &mut self.outer_r);
|
||||
|
||||
@@ -525,10 +525,10 @@ fn line_wire(from: Vec3, to: Vec3) -> WireModel {
|
||||
snap_pts: vec![],
|
||||
tangent_geoms: vec![],
|
||||
aci: 0,
|
||||
key_vertices: vec![],
|
||||
aabb: WireModel::UNBOUNDED_AABB,
|
||||
plinegen: true,
|
||||
vp_scissor: None,
|
||||
fill_tris: vec![],
|
||||
key_vertices: vec![],
|
||||
aabb: WireModel::UNBOUNDED_AABB,
|
||||
plinegen: true,
|
||||
vp_scissor: None,
|
||||
fill_tris: vec![],
|
||||
}
|
||||
}
|
||||
@@ -29,23 +29,34 @@ pub struct HatcheditCommand {
|
||||
|
||||
impl HatcheditCommand {
|
||||
pub fn new() -> Self {
|
||||
Self { step: HatcheditStep::PickHatch }
|
||||
Self {
|
||||
step: HatcheditStep::PickHatch,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_handle(handle: Handle, name: String, scale: f32, angle: f32) -> Self {
|
||||
Self {
|
||||
step: HatcheditStep::EditOptions { handle, name, scale, angle },
|
||||
step: HatcheditStep::EditOptions {
|
||||
handle,
|
||||
name,
|
||||
scale,
|
||||
angle,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CadCommand for HatcheditCommand {
|
||||
fn name(&self) -> &'static str { "HATCHEDIT" }
|
||||
fn name(&self) -> &'static str {
|
||||
"HATCHEDIT"
|
||||
}
|
||||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.step {
|
||||
HatcheditStep::PickHatch => "HATCHEDIT Select hatch:".into(),
|
||||
HatcheditStep::EditOptions { name, scale, angle, .. } => format!(
|
||||
HatcheditStep::EditOptions {
|
||||
name, scale, angle, ..
|
||||
} => format!(
|
||||
"HATCHEDIT Pattern:{name} Scale:{scale:.4} Angle:{angle:.1} \
|
||||
[P <pat> / S <scale> / A <angle> | Enter to apply]:"
|
||||
),
|
||||
@@ -57,7 +68,9 @@ impl CadCommand for HatcheditCommand {
|
||||
}
|
||||
|
||||
fn on_entity_pick(&mut self, handle: Handle, _pt: Vec3) -> CmdResult {
|
||||
if handle.is_null() { return CmdResult::NeedPoint; }
|
||||
if handle.is_null() {
|
||||
return CmdResult::NeedPoint;
|
||||
}
|
||||
// Actual hatch model retrieval happens in commands.rs dispatch.
|
||||
// Store handle; name/scale/angle filled in by dispatch.
|
||||
self.step = HatcheditStep::EditOptions {
|
||||
@@ -75,9 +88,12 @@ impl CadCommand for HatcheditCommand {
|
||||
|
||||
fn on_text_input(&mut self, text: &str) -> Option<CmdResult> {
|
||||
let (handle, name, scale, angle) = match &mut self.step {
|
||||
HatcheditStep::EditOptions { handle, name, scale, angle } => {
|
||||
(*handle, name, scale, angle)
|
||||
}
|
||||
HatcheditStep::EditOptions {
|
||||
handle,
|
||||
name,
|
||||
scale,
|
||||
angle,
|
||||
} => (*handle, name, scale, angle),
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
@@ -96,12 +112,16 @@ impl CadCommand for HatcheditCommand {
|
||||
// Parse option: P/S/A followed by value
|
||||
if let Some(rest) = text.strip_prefix('P') {
|
||||
let n = rest.trim().to_string();
|
||||
if !n.is_empty() { *name = n; }
|
||||
if !n.is_empty() {
|
||||
*name = n;
|
||||
}
|
||||
return Some(CmdResult::NeedPoint);
|
||||
}
|
||||
if let Some(rest) = text.strip_prefix('S') {
|
||||
if let Ok(v) = rest.trim().replace(',', ".").parse::<f32>() {
|
||||
if v > 0.0 { *scale = v; }
|
||||
if v > 0.0 {
|
||||
*scale = v;
|
||||
}
|
||||
}
|
||||
return Some(CmdResult::NeedPoint);
|
||||
}
|
||||
@@ -116,16 +136,28 @@ impl CadCommand for HatcheditCommand {
|
||||
Some(CmdResult::NeedPoint)
|
||||
}
|
||||
|
||||
fn on_point(&mut self, _pt: Vec3) -> CmdResult { CmdResult::NeedPoint }
|
||||
fn on_point(&mut self, _pt: Vec3) -> CmdResult {
|
||||
CmdResult::NeedPoint
|
||||
}
|
||||
fn on_enter(&mut self) -> CmdResult {
|
||||
// Enter without text → apply current settings
|
||||
let (handle, name, scale, angle) = match &self.step {
|
||||
HatcheditStep::EditOptions { handle, name, scale, angle } => {
|
||||
(*handle, name.clone(), *scale, *angle)
|
||||
}
|
||||
HatcheditStep::EditOptions {
|
||||
handle,
|
||||
name,
|
||||
scale,
|
||||
angle,
|
||||
} => (*handle, name.clone(), *scale, *angle),
|
||||
_ => return CmdResult::Cancel,
|
||||
};
|
||||
CmdResult::HatcheditApply { handle, name, scale, angle }
|
||||
CmdResult::HatcheditApply {
|
||||
handle,
|
||||
name,
|
||||
scale,
|
||||
angle,
|
||||
}
|
||||
}
|
||||
fn on_escape(&mut self) -> CmdResult {
|
||||
CmdResult::Cancel
|
||||
}
|
||||
fn on_escape(&mut self) -> CmdResult { CmdResult::Cancel }
|
||||
}
|
||||
@@ -23,16 +23,28 @@ pub struct MlineCommand {
|
||||
impl MlineCommand {
|
||||
#[allow(dead_code)]
|
||||
pub fn new() -> Self {
|
||||
Self { points: vec![], scale: 1.0, waiting_scale: false, style_name: "Standard".into() }
|
||||
Self {
|
||||
points: vec![],
|
||||
scale: 1.0,
|
||||
waiting_scale: false,
|
||||
style_name: "Standard".into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_style(style_name: impl Into<String>) -> Self {
|
||||
Self { points: vec![], scale: 1.0, waiting_scale: false, style_name: style_name.into() }
|
||||
Self {
|
||||
points: vec![],
|
||||
scale: 1.0,
|
||||
waiting_scale: false,
|
||||
style_name: style_name.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CadCommand for MlineCommand {
|
||||
fn name(&self) -> &'static str { "MLINE" }
|
||||
fn name(&self) -> &'static str {
|
||||
"MLINE"
|
||||
}
|
||||
|
||||
fn prompt(&self) -> String {
|
||||
if self.waiting_scale {
|
||||
@@ -40,7 +52,10 @@ impl CadCommand for MlineCommand {
|
||||
} else if self.points.is_empty() {
|
||||
format!("MLINE Specify start point (scale={:.2}):", self.scale)
|
||||
} else {
|
||||
format!("MLINE Specify next point ({} pts, Enter to finish, C to close, S to set scale):", self.points.len())
|
||||
format!(
|
||||
"MLINE Specify next point ({} pts, Enter to finish, C to close, S to set scale):",
|
||||
self.points.len()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +66,12 @@ impl CadCommand for MlineCommand {
|
||||
fn on_text_input(&mut self, text: &str) -> Option<CmdResult> {
|
||||
// Waiting for scale value
|
||||
if self.waiting_scale {
|
||||
let v: f64 = text.trim().replace(',', ".").parse().ok().filter(|&v: &f64| v > 0.0)?;
|
||||
let v: f64 = text
|
||||
.trim()
|
||||
.replace(',', ".")
|
||||
.parse()
|
||||
.ok()
|
||||
.filter(|&v: &f64| v > 0.0)?;
|
||||
self.scale = v;
|
||||
self.waiting_scale = false;
|
||||
return Some(CmdResult::NeedPoint);
|
||||
@@ -74,7 +94,9 @@ impl CadCommand for MlineCommand {
|
||||
// Scale: "S <value>" inline
|
||||
if let Some(rest) = up.strip_prefix("S ") {
|
||||
if let Ok(v) = rest.trim().replace(',', ".").parse::<f64>() {
|
||||
if v > 0.0 { self.scale = v; }
|
||||
if v > 0.0 {
|
||||
self.scale = v;
|
||||
}
|
||||
return Some(CmdResult::NeedPoint);
|
||||
}
|
||||
}
|
||||
@@ -96,9 +118,10 @@ impl CadCommand for MlineCommand {
|
||||
}
|
||||
|
||||
fn on_mouse_move(&mut self, pt: Vec3) -> Option<WireModel> {
|
||||
if self.points.is_empty() { return None; }
|
||||
let mut pts: Vec<[f32; 3]> =
|
||||
self.points.iter().map(|p| [p.x, p.y, p.z]).collect();
|
||||
if self.points.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let mut pts: Vec<[f32; 3]> = self.points.iter().map(|p| [p.x, p.y, p.z]).collect();
|
||||
pts.push([pt.x, pt.y, pt.z]);
|
||||
Some(WireModel {
|
||||
name: "mline_preview".into(),
|
||||
@@ -121,7 +144,8 @@ impl CadCommand for MlineCommand {
|
||||
}
|
||||
|
||||
fn build_mline(pts: &[Vec3], scale: f64, closed: bool, style_name: &str) -> EntityType {
|
||||
let verts: Vec<Vector3> = pts.iter()
|
||||
let verts: Vec<Vector3> = pts
|
||||
.iter()
|
||||
.map(|p| Vector3::new(p.x as f64, p.z as f64, p.y as f64))
|
||||
.collect();
|
||||
let mut mline = if closed {
|
||||
|
||||
@@ -3,8 +3,8 @@ pub mod attdef;
|
||||
pub mod circle;
|
||||
pub mod donut;
|
||||
pub mod ellipse;
|
||||
pub mod hatchedit;
|
||||
pub mod hatch;
|
||||
pub mod hatchedit;
|
||||
pub mod line;
|
||||
pub mod mline;
|
||||
pub mod point;
|
||||
|
||||
@@ -130,7 +130,8 @@ fn update_tangent_after_arc(tangent: &mut Option<Vec2>, bulge: f64) {
|
||||
// the entry tangent rotated by that angle.
|
||||
let theta = 4.0 * (bulge as f32).atan();
|
||||
let (sin_t, cos_t) = theta.sin_cos();
|
||||
*tangent = Some(Vec2::new(t.x * cos_t - t.y * sin_t, t.x * sin_t + t.y * cos_t).normalize_or_zero());
|
||||
*tangent =
|
||||
Some(Vec2::new(t.x * cos_t - t.y * sin_t, t.x * sin_t + t.y * cos_t).normalize_or_zero());
|
||||
}
|
||||
|
||||
/// Sample a circular arc defined by bulge into `n` line-segment points.
|
||||
@@ -169,7 +170,11 @@ fn arc_sample_points(a: Vec3, bulge: f64, b: Vec3, n: usize) -> Vec<[f32; 3]> {
|
||||
for i in 0..=n {
|
||||
let t = i as f64 / n as f64;
|
||||
let angle = start_angle + t * theta;
|
||||
pts.push([(cx + r * angle.cos()) as f32, (cy + r * angle.sin()) as f32, a.z]);
|
||||
pts.push([
|
||||
(cx + r * angle.cos()) as f32,
|
||||
(cy + r * angle.sin()) as f32,
|
||||
a.z,
|
||||
]);
|
||||
}
|
||||
pts
|
||||
}
|
||||
@@ -308,6 +313,11 @@ impl CadCommand for PlineCommand {
|
||||
}
|
||||
}
|
||||
|
||||
Some(WireModel::solid("rubber_band".into(), pts, WireModel::CYAN, false))
|
||||
Some(WireModel::solid(
|
||||
"rubber_band".into(),
|
||||
pts,
|
||||
WireModel::CYAN,
|
||||
false,
|
||||
))
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,12 @@ pub struct ImageCommand {
|
||||
|
||||
impl ImageCommand {
|
||||
pub fn new(file_path: String, pixel_width: u32, pixel_height: u32) -> Self {
|
||||
Self { file_path, pixel_width, pixel_height, origin: None }
|
||||
Self {
|
||||
file_path,
|
||||
pixel_width,
|
||||
pixel_height,
|
||||
origin: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn aspect(&self) -> f64 {
|
||||
@@ -61,7 +66,10 @@ impl CadCommand for ImageCommand {
|
||||
|
||||
fn prompt(&self) -> String {
|
||||
if self.origin.is_none() {
|
||||
format!("IMAGE Specify insertion point ({}): ", short_name(&self.file_path))
|
||||
format!(
|
||||
"IMAGE Specify insertion point ({}): ",
|
||||
short_name(&self.file_path)
|
||||
)
|
||||
} else {
|
||||
"IMAGE Specify width (drag right):".into()
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
use acadrust::entities::LwPolyline;
|
||||
use acadrust::types::Vector2;
|
||||
use acadrust::{EntityType, entities::LwVertex};
|
||||
use acadrust::{entities::LwVertex, EntityType};
|
||||
use glam::Vec3;
|
||||
|
||||
use crate::command::{CadCommand, CmdResult};
|
||||
@@ -41,13 +41,21 @@ impl RevCloudCommand {
|
||||
}
|
||||
|
||||
impl CadCommand for RevCloudCommand {
|
||||
fn name(&self) -> &'static str { "REVCLOUD" }
|
||||
fn name(&self) -> &'static str {
|
||||
"REVCLOUD"
|
||||
}
|
||||
|
||||
fn prompt(&self) -> String {
|
||||
if self.points.is_empty() {
|
||||
format!("REVCLOUD Specify start point (arc length = {:.2}):", self.arc_length)
|
||||
format!(
|
||||
"REVCLOUD Specify start point (arc length = {:.2}):",
|
||||
self.arc_length
|
||||
)
|
||||
} else {
|
||||
format!("REVCLOUD Specify next point ({} pts, Enter to close):", self.points.len())
|
||||
format!(
|
||||
"REVCLOUD Specify next point ({} pts, Enter to close):",
|
||||
self.points.len()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,9 +73,10 @@ impl CadCommand for RevCloudCommand {
|
||||
}
|
||||
|
||||
fn on_mouse_move(&mut self, pt: Vec3) -> Option<WireModel> {
|
||||
if self.points.is_empty() { return None; }
|
||||
let mut preview_pts: Vec<[f32; 3]> =
|
||||
self.points.iter().map(|p| [p.x, p.y, p.z]).collect();
|
||||
if self.points.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let mut preview_pts: Vec<[f32; 3]> = self.points.iter().map(|p| [p.x, p.y, p.z]).collect();
|
||||
preview_pts.push([pt.x, pt.y, pt.z]);
|
||||
preview_pts.push([self.points[0].x, self.points[0].y, self.points[0].z]);
|
||||
Some(WireModel {
|
||||
@@ -101,7 +110,9 @@ fn make_revcloud(pts: &[Vec3], arc_len: f64) -> EntityType {
|
||||
let p0 = pts[i];
|
||||
let p1 = pts[(i + 1) % n];
|
||||
let seg_len = ((p1.x - p0.x).powi(2) + (p1.z - p0.z).powi(2)).sqrt() as f64;
|
||||
if seg_len < 1e-6 { continue; }
|
||||
if seg_len < 1e-6 {
|
||||
continue;
|
||||
}
|
||||
|
||||
// How many full arcs fit?
|
||||
let num_arcs = ((seg_len / arc_len).round() as usize).max(1);
|
||||
|
||||
@@ -37,15 +37,25 @@ enum WipeoutMode {
|
||||
|
||||
impl WipeoutCommand {
|
||||
pub fn new_rectangular() -> Self {
|
||||
Self { mode: WipeoutMode::Rectangular, first: None, poly_pts: vec![] }
|
||||
Self {
|
||||
mode: WipeoutMode::Rectangular,
|
||||
first: None,
|
||||
poly_pts: vec![],
|
||||
}
|
||||
}
|
||||
pub fn new_polygonal() -> Self {
|
||||
Self { mode: WipeoutMode::Polygonal, first: None, poly_pts: vec![] }
|
||||
Self {
|
||||
mode: WipeoutMode::Polygonal,
|
||||
first: None,
|
||||
poly_pts: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CadCommand for WipeoutCommand {
|
||||
fn name(&self) -> &'static str { "WIPEOUT" }
|
||||
fn name(&self) -> &'static str {
|
||||
"WIPEOUT"
|
||||
}
|
||||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.mode {
|
||||
@@ -60,7 +70,10 @@ impl CadCommand for WipeoutCommand {
|
||||
if self.poly_pts.is_empty() {
|
||||
"WIPEOUT (Polygon) Specify first point:".into()
|
||||
} else {
|
||||
format!("WIPEOUT (Polygon) Specify next point ({} pts, Enter to close):", self.poly_pts.len())
|
||||
format!(
|
||||
"WIPEOUT (Polygon) Specify next point ({} pts, Enter to close):",
|
||||
self.poly_pts.len()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -117,15 +130,17 @@ impl CadCommand for WipeoutCommand {
|
||||
snap_pts: vec![],
|
||||
tangent_geoms: vec![],
|
||||
aci: 0,
|
||||
key_vertices: vec![],
|
||||
aabb: WireModel::UNBOUNDED_AABB,
|
||||
plinegen: true,
|
||||
vp_scissor: None,
|
||||
fill_tris: vec![],
|
||||
key_vertices: vec![],
|
||||
aabb: WireModel::UNBOUNDED_AABB,
|
||||
plinegen: true,
|
||||
vp_scissor: None,
|
||||
fill_tris: vec![],
|
||||
})
|
||||
}
|
||||
WipeoutMode::Polygonal => {
|
||||
if self.poly_pts.is_empty() { return None; }
|
||||
if self.poly_pts.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let mut pts: Vec<[f32; 3]> =
|
||||
self.poly_pts.iter().map(|p| [p.x, p.y, p.z]).collect();
|
||||
pts.push([pt.x, pt.y, pt.z]);
|
||||
@@ -141,11 +156,11 @@ impl CadCommand for WipeoutCommand {
|
||||
snap_pts: vec![],
|
||||
tangent_geoms: vec![],
|
||||
aci: 0,
|
||||
key_vertices: vec![],
|
||||
aabb: WireModel::UNBOUNDED_AABB,
|
||||
plinegen: true,
|
||||
vp_scissor: None,
|
||||
fill_tris: vec![],
|
||||
key_vertices: vec![],
|
||||
aabb: WireModel::UNBOUNDED_AABB,
|
||||
plinegen: true,
|
||||
vp_scissor: None,
|
||||
fill_tris: vec![],
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -154,23 +169,16 @@ impl CadCommand for WipeoutCommand {
|
||||
|
||||
fn make_rect_wipeout(p1: Vec3, p2: Vec3) -> EntityType {
|
||||
// Y-up world: X→DXF X, Z→DXF Y, Y→DXF Z
|
||||
let c1 = Vector3::new(
|
||||
p1.x.min(p2.x) as f64,
|
||||
p1.z.min(p2.z) as f64,
|
||||
p1.y as f64,
|
||||
);
|
||||
let c2 = Vector3::new(
|
||||
p1.x.max(p2.x) as f64,
|
||||
p1.z.max(p2.z) as f64,
|
||||
p1.y as f64,
|
||||
);
|
||||
let c1 = Vector3::new(p1.x.min(p2.x) as f64, p1.z.min(p2.z) as f64, p1.y as f64);
|
||||
let c2 = Vector3::new(p1.x.max(p2.x) as f64, p1.z.max(p2.z) as f64, p1.y as f64);
|
||||
EntityType::Wipeout(Wipeout::from_corners(c1, c2))
|
||||
}
|
||||
|
||||
fn make_poly_wipeout(pts: &[Vec3]) -> EntityType {
|
||||
use acadrust::types::Vector2;
|
||||
let z = pts[0].y as f64;
|
||||
let verts: Vec<Vector2> = pts.iter()
|
||||
let verts: Vec<Vector2> = pts
|
||||
.iter()
|
||||
.map(|p| Vector2::new(p.x as f64, p.z as f64))
|
||||
.collect();
|
||||
EntityType::Wipeout(Wipeout::polygonal(&verts, z))
|
||||
|
||||
Reference in new issue
Block a user