cargo fmt

This commit is contained in:
Hakan committed 2026-05-12 10:36:15 +03:00
1 parent 468cbde5e1
commit ca07268c7c
204 files changed
+13997 -5525

No files matched your search

+285 -91
View File
@@ -26,9 +26,15 @@ use crate::scene::truck_tess;
fn solid_to_mesh(solid: &truck_modeling::Solid, color: [f32; 4], name: &str) -> Option<MeshModel> {
match truck_tess::tessellate_solid(solid, [0.0; 3]) {
truck_tess::TruckTessResult::Mesh { verts, normals, indices } => Some(MeshModel {
truck_tess::TruckTessResult::Mesh {
verts,
normals,
indices,
} => Some(MeshModel {
name: name.to_string(),
verts, normals, indices,
verts,
normals,
indices,
color,
selected: false,
}),
@@ -38,9 +44,15 @@ fn solid_to_mesh(solid: &truck_modeling::Solid, color: [f32; 4], name: &str) ->
fn shell_to_mesh(shell: &truck_modeling::Shell, color: [f32; 4], name: &str) -> Option<MeshModel> {
match truck_tess::tessellate_shell(shell, [0.0; 3]) {
truck_tess::TruckTessResult::Mesh { verts, normals, indices } => Some(MeshModel {
truck_tess::TruckTessResult::Mesh {
verts,
normals,
indices,
} => Some(MeshModel {
name: name.to_string(),
verts, normals, indices,
verts,
normals,
indices,
color,
selected: false,
}),
@@ -58,36 +70,67 @@ pub struct BoxCommand {
}
#[derive(PartialEq)]
enum BoxStep { Corner1, Corner2, Height }
enum BoxStep {
Corner1,
Corner2,
Height,
}
impl BoxCommand {
pub fn new(color: [f32; 4]) -> Self {
Self { step: BoxStep::Corner1, p1: Vec3::ZERO, p2: Vec3::ZERO, color }
Self {
step: BoxStep::Corner1,
p1: Vec3::ZERO,
p2: Vec3::ZERO,
color,
}
}
}
impl CadCommand for BoxCommand {
fn name(&self) -> &'static str { "BOX" }
fn name(&self) -> &'static str {
"BOX"
}
fn prompt(&self) -> String {
match self.step {
BoxStep::Corner1 => "BOX First corner:".into(),
BoxStep::Corner2 => "BOX Opposite corner (XY):".into(),
BoxStep::Height => "BOX Height:".into(),
BoxStep::Height => "BOX Height:".into(),
}
}
fn on_point(&mut self, pt: Vec3) -> CmdResult {
match self.step {
BoxStep::Corner1 => { self.p1 = pt; self.step = BoxStep::Corner2; CmdResult::NeedPoint }
BoxStep::Corner2 => { self.p2 = pt; self.step = BoxStep::Height; CmdResult::NeedPoint }
BoxStep::Height => commit_box(self.p1, self.p2, (pt.y - self.p1.y).abs().max(1e-4), self.color),
BoxStep::Corner1 => {
self.p1 = pt;
self.step = BoxStep::Corner2;
CmdResult::NeedPoint
}
BoxStep::Corner2 => {
self.p2 = pt;
self.step = BoxStep::Height;
CmdResult::NeedPoint
}
BoxStep::Height => commit_box(
self.p1,
self.p2,
(pt.y - self.p1.y).abs().max(1e-4),
self.color,
),
}
}
fn wants_text_input(&self) -> bool { self.step == BoxStep::Height }
fn wants_text_input(&self) -> bool {
self.step == BoxStep::Height
}
fn on_text_input(&mut self, text: &str) -> Option<CmdResult> {
text.trim().parse::<f32>().ok().filter(|&h| h.abs() > 1e-6)
text.trim()
.parse::<f32>()
.ok()
.filter(|&h| h.abs() > 1e-6)
.map(|h| commit_box(self.p1, self.p2, h.abs(), self.color))
}
fn on_enter(&mut self) -> CmdResult { CmdResult::Cancel }
fn on_enter(&mut self) -> CmdResult {
CmdResult::Cancel
}
}
fn commit_box(p1: Vec3, p2: Vec3, height: f32, color: [f32; 4]) -> CmdResult {
@@ -97,7 +140,7 @@ fn commit_box(p1: Vec3, p2: Vec3, height: f32, color: [f32; 4]) -> CmdResult {
let x1 = p1.x.max(p2.x) as f64;
let y1 = p1.z.max(p2.z) as f64;
let z0 = p1.y as f64;
let h = height as f64;
let h = height as f64;
// Build face at z=z0, then sweep to z0+h.
let v00 = builder::vertex(Point3::new(x0, y0, z0));
@@ -115,7 +158,9 @@ fn commit_box(p1: Vec3, p2: Vec3, height: f32, color: [f32; 4]) -> CmdResult {
};
// tsweep on Face → Solid
let solid = builder::tsweep(&face, TruckVec3::new(0.0, 0.0, h));
CmdResult::CommitSolid3D { mesh_fn: Box::new(move |name| solid_to_mesh(&solid, color, &name)) }
CmdResult::CommitSolid3D {
mesh_fn: Box::new(move |name| solid_to_mesh(&solid, color, &name)),
}
}
// ── SPHERE command ─────────────────────────────────────────────────────────
@@ -127,16 +172,25 @@ pub struct SphereCommand {
}
#[derive(PartialEq)]
enum SphereStep { Center, Radius }
enum SphereStep {
Center,
Radius,
}
impl SphereCommand {
pub fn new(color: [f32; 4]) -> Self {
Self { step: SphereStep::Center, center: Vec3::ZERO, color }
Self {
step: SphereStep::Center,
center: Vec3::ZERO,
color,
}
}
}
impl CadCommand for SphereCommand {
fn name(&self) -> &'static str { "SPHERE" }
fn name(&self) -> &'static str {
"SPHERE"
}
fn prompt(&self) -> String {
match self.step {
SphereStep::Center => "SPHERE Center:".into(),
@@ -145,35 +199,50 @@ impl CadCommand for SphereCommand {
}
fn on_point(&mut self, pt: Vec3) -> CmdResult {
match self.step {
SphereStep::Center => { self.center = pt; self.step = SphereStep::Radius; CmdResult::NeedPoint }
SphereStep::Radius => commit_sphere(self.center, (pt - self.center).length(), self.color),
SphereStep::Center => {
self.center = pt;
self.step = SphereStep::Radius;
CmdResult::NeedPoint
}
SphereStep::Radius => {
commit_sphere(self.center, (pt - self.center).length(), self.color)
}
}
}
fn wants_text_input(&self) -> bool { self.step == SphereStep::Radius }
fn wants_text_input(&self) -> bool {
self.step == SphereStep::Radius
}
fn on_text_input(&mut self, text: &str) -> Option<CmdResult> {
text.trim().parse::<f32>().ok().filter(|&r| r > 1e-6)
text.trim()
.parse::<f32>()
.ok()
.filter(|&r| r > 1e-6)
.map(|r| commit_sphere(self.center, r, self.color))
}
fn on_enter(&mut self) -> CmdResult { CmdResult::Cancel }
fn on_enter(&mut self) -> CmdResult {
CmdResult::Cancel
}
}
fn commit_sphere(center: Vec3, radius: f32, color: [f32; 4]) -> CmdResult {
let cx = center.x as f64;
let cy = center.z as f64;
let cz = center.y as f64;
let r = radius as f64;
let r = radius as f64;
// Build a half-circle arc wire from north pole to south pole (XZ plane).
let north = builder::vertex(Point3::new(cx, cy, cz + r));
let south = builder::vertex(Point3::new(cx, cy, cz - r));
let east = Point3::new(cx + r, cy, cz);
let arc = builder::circle_arc(&north, &south, east);
let east = Point3::new(cx + r, cy, cz);
let arc = builder::circle_arc(&north, &south, east);
// rsweep the wire around the Z axis for a full revolution → Shell.
let wire: truck_modeling::Wire = std::iter::once(arc).collect();
let axis_pt = Point3::new(cx, cy, cz);
let axis = TruckVec3::new(0.0, 0.0, 1.0);
let shell = builder::rsweep(&wire, axis_pt, axis, Rad(std::f64::consts::TAU));
CmdResult::CommitSolid3D { mesh_fn: Box::new(move |name| shell_to_mesh(&shell, color, &name)) }
let axis = TruckVec3::new(0.0, 0.0, 1.0);
let shell = builder::rsweep(&wire, axis_pt, axis, Rad(std::f64::consts::TAU));
CmdResult::CommitSolid3D {
mesh_fn: Box::new(move |name| shell_to_mesh(&shell, color, &name)),
}
}
// ── CYLINDER command ───────────────────────────────────────────────────────
@@ -186,16 +255,27 @@ pub struct CylinderCommand {
}
#[derive(PartialEq)]
enum CylStep { Center, Radius, Height }
enum CylStep {
Center,
Radius,
Height,
}
impl CylinderCommand {
pub fn new(color: [f32; 4]) -> Self {
Self { step: CylStep::Center, center: Vec3::ZERO, radius: 1.0, color }
Self {
step: CylStep::Center,
center: Vec3::ZERO,
radius: 1.0,
color,
}
}
}
impl CadCommand for CylinderCommand {
fn name(&self) -> &'static str { "CYLINDER" }
fn name(&self) -> &'static str {
"CYLINDER"
}
fn prompt(&self) -> String {
match self.step {
CylStep::Center => "CYLINDER Center of base:".into(),
@@ -205,37 +285,54 @@ impl CadCommand for CylinderCommand {
}
fn on_point(&mut self, pt: Vec3) -> CmdResult {
match self.step {
CylStep::Center => { self.center = pt; self.step = CylStep::Radius; CmdResult::NeedPoint }
CylStep::Center => {
self.center = pt;
self.step = CylStep::Radius;
CmdResult::NeedPoint
}
CylStep::Radius => {
self.radius = (pt - self.center).length().max(1e-4);
self.step = CylStep::Height;
CmdResult::NeedPoint
}
CylStep::Height => commit_cylinder(self.center, self.radius, (pt.y - self.center.y).abs().max(1e-4), self.color),
CylStep::Height => commit_cylinder(
self.center,
self.radius,
(pt.y - self.center.y).abs().max(1e-4),
self.color,
),
}
}
fn wants_text_input(&self) -> bool { matches!(self.step, CylStep::Radius | CylStep::Height) }
fn wants_text_input(&self) -> bool {
matches!(self.step, CylStep::Radius | CylStep::Height)
}
fn on_text_input(&mut self, text: &str) -> Option<CmdResult> {
let v = text.trim().parse::<f32>().ok().filter(|&v| v > 1e-6)?;
match self.step {
CylStep::Radius => { self.radius = v; self.step = CylStep::Height; Some(CmdResult::NeedPoint) }
CylStep::Radius => {
self.radius = v;
self.step = CylStep::Height;
Some(CmdResult::NeedPoint)
}
CylStep::Height => Some(commit_cylinder(self.center, self.radius, v, self.color)),
_ => None,
}
}
fn on_enter(&mut self) -> CmdResult { CmdResult::Cancel }
fn on_enter(&mut self) -> CmdResult {
CmdResult::Cancel
}
}
fn commit_cylinder(center: Vec3, radius: f32, height: f32, color: [f32; 4]) -> CmdResult {
let cx = center.x as f64;
let cy = center.z as f64;
let cz = center.y as f64;
let r = radius as f64;
let h = height as f64;
let r = radius as f64;
let h = height as f64;
// Build circle face at z=cz, sweep upward.
let right = builder::vertex(Point3::new(cx + r, cy, cz));
let left = builder::vertex(Point3::new(cx - r, cy, cz));
let left = builder::vertex(Point3::new(cx - r, cy, cz));
let top_t = Point3::new(cx, cy + r, cz);
let bot_t = Point3::new(cx, cy - r, cz);
let upper = builder::circle_arc(&right, &left, top_t);
@@ -246,7 +343,9 @@ fn commit_cylinder(center: Vec3, radius: f32, height: f32, color: [f32; 4]) -> C
Err(_) => return CmdResult::Cancel,
};
let solid = builder::tsweep(&face, TruckVec3::new(0.0, 0.0, h));
CmdResult::CommitSolid3D { mesh_fn: Box::new(move |name| solid_to_mesh(&solid, color, &name)) }
CmdResult::CommitSolid3D {
mesh_fn: Box::new(move |name| solid_to_mesh(&solid, color, &name)),
}
}
// ── EXTRUDE command ────────────────────────────────────────────────────────
@@ -258,41 +357,69 @@ pub struct ExtrudeCommand {
}
#[derive(PartialEq)]
enum ExtrudeStep { Pick, Height }
enum ExtrudeStep {
Pick,
Height,
}
impl ExtrudeCommand {
pub fn new(color: [f32; 4]) -> Self {
Self { step: ExtrudeStep::Pick, target_handle: acadrust::Handle::NULL, color }
Self {
step: ExtrudeStep::Pick,
target_handle: acadrust::Handle::NULL,
color,
}
}
}
impl CadCommand for ExtrudeCommand {
fn name(&self) -> &'static str { "EXTRUDE" }
fn name(&self) -> &'static str {
"EXTRUDE"
}
fn prompt(&self) -> String {
match self.step {
ExtrudeStep::Pick => "EXTRUDE Select closed profile (Circle, LwPolyline…):".into(),
ExtrudeStep::Pick => "EXTRUDE Select closed profile (Circle, LwPolyline…):".into(),
ExtrudeStep::Height => "EXTRUDE Height:".into(),
}
}
fn needs_entity_pick(&self) -> bool { self.step == ExtrudeStep::Pick }
fn needs_entity_pick(&self) -> bool {
self.step == ExtrudeStep::Pick
}
fn on_entity_pick(&mut self, handle: acadrust::Handle, _pt: Vec3) -> CmdResult {
if handle.is_null() { return CmdResult::NeedPoint; }
if handle.is_null() {
return CmdResult::NeedPoint;
}
self.target_handle = handle;
self.step = ExtrudeStep::Height;
CmdResult::NeedPoint
}
fn on_point(&mut self, pt: Vec3) -> CmdResult {
if self.step == ExtrudeStep::Height {
return CmdResult::ExtrudeEntity { handle: self.target_handle, height: pt.y.abs().max(1e-4), color: self.color };
return CmdResult::ExtrudeEntity {
handle: self.target_handle,
height: pt.y.abs().max(1e-4),
color: self.color,
};
}
CmdResult::NeedPoint
}
fn wants_text_input(&self) -> bool { self.step == ExtrudeStep::Height }
fn wants_text_input(&self) -> bool {
self.step == ExtrudeStep::Height
}
fn on_text_input(&mut self, text: &str) -> Option<CmdResult> {
text.trim().parse::<f32>().ok().filter(|&h| h.abs() > 1e-6)
.map(|h| CmdResult::ExtrudeEntity { handle: self.target_handle, height: h.abs(), color: self.color })
text.trim()
.parse::<f32>()
.ok()
.filter(|&h| h.abs() > 1e-6)
.map(|h| CmdResult::ExtrudeEntity {
handle: self.target_handle,
height: h.abs(),
color: self.color,
})
}
fn on_enter(&mut self) -> CmdResult {
CmdResult::Cancel
}
fn on_enter(&mut self) -> CmdResult { CmdResult::Cancel }
}
// ── REVOLVE command ────────────────────────────────────────────────────────
@@ -306,7 +433,12 @@ pub struct RevolveCommand {
}
#[derive(PartialEq)]
enum RevolveStep { Pick, AxisStart, AxisEnd, Angle }
enum RevolveStep {
Pick,
AxisStart,
AxisEnd,
Angle,
}
impl RevolveCommand {
pub fn new(color: [f32; 4]) -> Self {
@@ -321,38 +453,64 @@ impl RevolveCommand {
}
impl CadCommand for RevolveCommand {
fn name(&self) -> &'static str { "REVOLVE" }
fn name(&self) -> &'static str {
"REVOLVE"
}
fn prompt(&self) -> String {
match self.step {
RevolveStep::Pick => "REVOLVE Select profile:".into(),
RevolveStep::Pick => "REVOLVE Select profile:".into(),
RevolveStep::AxisStart => "REVOLVE Axis start point:".into(),
RevolveStep::AxisEnd => "REVOLVE Axis end point:".into(),
RevolveStep::Angle => "REVOLVE Angle of revolution <360>:".into(),
RevolveStep::AxisEnd => "REVOLVE Axis end point:".into(),
RevolveStep::Angle => "REVOLVE Angle of revolution <360>:".into(),
}
}
fn needs_entity_pick(&self) -> bool { self.step == RevolveStep::Pick }
fn needs_entity_pick(&self) -> bool {
self.step == RevolveStep::Pick
}
fn on_entity_pick(&mut self, handle: acadrust::Handle, _pt: Vec3) -> CmdResult {
if handle.is_null() { return CmdResult::NeedPoint; }
if handle.is_null() {
return CmdResult::NeedPoint;
}
self.target_handle = handle;
self.step = RevolveStep::AxisStart;
CmdResult::NeedPoint
}
fn on_point(&mut self, pt: Vec3) -> CmdResult {
match self.step {
RevolveStep::AxisStart => { self.axis_start = pt; self.step = RevolveStep::AxisEnd; CmdResult::NeedPoint }
RevolveStep::AxisEnd => { self.axis_end = pt; self.step = RevolveStep::Angle; CmdResult::NeedPoint }
RevolveStep::Angle => self.make_revolve(360.0),
RevolveStep::AxisStart => {
self.axis_start = pt;
self.step = RevolveStep::AxisEnd;
CmdResult::NeedPoint
}
RevolveStep::AxisEnd => {
self.axis_end = pt;
self.step = RevolveStep::Angle;
CmdResult::NeedPoint
}
RevolveStep::Angle => self.make_revolve(360.0),
_ => CmdResult::NeedPoint,
}
}
fn wants_text_input(&self) -> bool { self.step == RevolveStep::Angle }
fn wants_text_input(&self) -> bool {
self.step == RevolveStep::Angle
}
fn on_text_input(&mut self, text: &str) -> Option<CmdResult> {
let angle = if text.trim().is_empty() { 360.0f32 }
else { text.trim().parse::<f32>().ok().filter(|&a| a.abs() > 1e-3)? };
let angle = if text.trim().is_empty() {
360.0f32
} else {
text.trim()
.parse::<f32>()
.ok()
.filter(|&a| a.abs() > 1e-3)?
};
Some(self.make_revolve(angle.abs()))
}
fn on_enter(&mut self) -> CmdResult {
if self.step == RevolveStep::Angle { self.make_revolve(360.0) } else { CmdResult::Cancel }
if self.step == RevolveStep::Angle {
self.make_revolve(360.0)
} else {
CmdResult::Cancel
}
}
}
@@ -377,42 +535,57 @@ pub struct SweepCommand {
}
#[derive(PartialEq)]
enum SweepStep { PickProfile, PickPath }
enum SweepStep {
PickProfile,
PickPath,
}
impl SweepCommand {
pub fn new(color: [f32; 4]) -> Self {
Self { step: SweepStep::PickProfile, profile_handle: acadrust::Handle::NULL, color }
Self {
step: SweepStep::PickProfile,
profile_handle: acadrust::Handle::NULL,
color,
}
}
}
impl CadCommand for SweepCommand {
fn name(&self) -> &'static str { "SWEEP" }
fn name(&self) -> &'static str {
"SWEEP"
}
fn prompt(&self) -> String {
match self.step {
SweepStep::PickProfile => "SWEEP Select profile to sweep:".into(),
SweepStep::PickPath => "SWEEP Select path (Line, Arc, LwPolyline):".into(),
SweepStep::PickPath => "SWEEP Select path (Line, Arc, LwPolyline):".into(),
}
}
fn needs_entity_pick(&self) -> bool { true }
fn needs_entity_pick(&self) -> bool {
true
}
fn on_entity_pick(&mut self, handle: acadrust::Handle, _pt: Vec3) -> CmdResult {
if handle.is_null() { return CmdResult::NeedPoint; }
if handle.is_null() {
return CmdResult::NeedPoint;
}
match self.step {
SweepStep::PickProfile => {
self.profile_handle = handle;
self.step = SweepStep::PickPath;
CmdResult::NeedPoint
}
SweepStep::PickPath => {
CmdResult::SweepEntity {
profile_handle: self.profile_handle,
path_handle: handle,
color: self.color,
}
}
SweepStep::PickPath => CmdResult::SweepEntity {
profile_handle: self.profile_handle,
path_handle: handle,
color: self.color,
},
}
}
fn on_point(&mut self, _pt: Vec3) -> CmdResult { CmdResult::NeedPoint }
fn on_enter(&mut self) -> CmdResult { CmdResult::Cancel }
fn on_point(&mut self, _pt: Vec3) -> CmdResult {
CmdResult::NeedPoint
}
fn on_enter(&mut self) -> CmdResult {
CmdResult::Cancel
}
}
// ── LOFT command ───────────────────────────────────────────────────────────
@@ -424,36 +597,57 @@ pub struct LoftCommand {
impl LoftCommand {
pub fn new(color: [f32; 4]) -> Self {
Self { profiles: Vec::new(), color }
Self {
profiles: Vec::new(),
color,
}
}
}
impl CadCommand for LoftCommand {
fn name(&self) -> &'static str { "LOFT" }
fn name(&self) -> &'static str {
"LOFT"
}
fn prompt(&self) -> String {
if self.profiles.is_empty() {
"LOFT Select first cross-section:".into()
} else {
format!("LOFT Select next cross-section ({} selected, Enter to finish):", self.profiles.len())
format!(
"LOFT Select next cross-section ({} selected, Enter to finish):",
self.profiles.len()
)
}
}
fn needs_entity_pick(&self) -> bool { true }
fn needs_entity_pick(&self) -> bool {
true
}
fn on_entity_pick(&mut self, handle: acadrust::Handle, _pt: Vec3) -> CmdResult {
if handle.is_null() { return CmdResult::NeedPoint; }
if handle.is_null() {
return CmdResult::NeedPoint;
}
// Avoid duplicate picks.
if !self.profiles.contains(&handle) {
self.profiles.push(handle);
}
CmdResult::NeedPoint
}
fn on_point(&mut self, _pt: Vec3) -> CmdResult { CmdResult::NeedPoint }
fn wants_text_input(&self) -> bool { self.profiles.len() >= 2 }
fn on_text_input(&mut self, _text: &str) -> Option<CmdResult> { None }
fn on_point(&mut self, _pt: Vec3) -> CmdResult {
CmdResult::NeedPoint
}
fn wants_text_input(&self) -> bool {
self.profiles.len() >= 2
}
fn on_text_input(&mut self, _text: &str) -> Option<CmdResult> {
None
}
fn on_enter(&mut self) -> CmdResult {
if self.profiles.len() < 2 {
CmdResult::Cancel
} else {
CmdResult::LoftEntities { handles: self.profiles.clone(), color: self.color }
CmdResult::LoftEntities {
handles: self.profiles.clone(),
color: self.color,
}
}
}
}