forked from 1b-agent/opencadstudio-upstream
fix(polyline): render fill mode boundaries
Use kernel-produced band outlines when FILLMODE is off. Preserve centerline linetype stations through inserts, clipping, projection, and PDF export.
This commit is contained in:
commit
4209c35ba3
60 files changed
+1620
-575
No files matched your search
@@ -222,6 +222,7 @@ impl CadCommand for AlignedDimensionCommand {
|
||||
Some(WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
@@ -281,6 +282,7 @@ fn preview_aligned(p1: DVec3, p2: DVec3, dim_pt: DVec3) -> WireModel {
|
||||
WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
@@ -163,6 +163,7 @@ fn preview_wire(points: Vec<Vec3>) -> WireModel {
|
||||
WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
@@ -194,6 +194,7 @@ fn preview_line(a: Vec3, b: Vec3) -> WireModel {
|
||||
WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
@@ -182,6 +182,7 @@ impl CadCommand for DimBaselineCommand {
|
||||
Some(WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
@@ -162,6 +162,7 @@ impl CadCommand for DimContinueCommand {
|
||||
Some(WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
@@ -88,6 +88,7 @@ impl CadCommand for DimJogLineCommand {
|
||||
Some(WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
@@ -105,6 +105,7 @@ impl CadCommand for DimTeditCommand {
|
||||
Some(WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
@@ -302,6 +302,7 @@ fn preview_wire(pts: &[Vec3], arrow_size: f32) -> WireModel {
|
||||
WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
@@ -239,6 +239,7 @@ fn preview_wire(points: Vec<DVec3>) -> WireModel {
|
||||
WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
@@ -229,6 +229,7 @@ fn preview_wire(pts: &[Vec3], arrow_size: f32) -> WireModel {
|
||||
WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
@@ -464,6 +464,7 @@ fn preview_wire(pts: &[Vec3]) -> WireModel {
|
||||
WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
@@ -139,6 +139,7 @@ fn preview_wire(points: Vec<Vec3>) -> WireModel {
|
||||
WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
@@ -95,6 +95,7 @@ impl CadCommand for QdimCommand {
|
||||
Some(WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
@@ -199,6 +199,7 @@ fn preview_wire(points: Vec<Vec3>) -> WireModel {
|
||||
WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
@@ -201,6 +201,7 @@ impl CadCommand for TableCommand {
|
||||
Some(WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
@@ -105,6 +105,7 @@ impl CadCommand for ToleranceCommand {
|
||||
Some(WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
@@ -26,6 +26,8 @@ thread_local! {
|
||||
static RECT_CHAMFER1: Cell<f64> = Cell::new(0.0);
|
||||
static RECT_CHAMFER2: Cell<f64> = Cell::new(0.0);
|
||||
static RECT_FILLET: Cell<f64> = Cell::new(0.0);
|
||||
static DONUT_INNER_DIAMETER: Cell<f64> = Cell::new(0.5);
|
||||
static DONUT_OUTER_DIAMETER: Cell<f64> = Cell::new(1.0);
|
||||
}
|
||||
|
||||
macro_rules! accessors {
|
||||
@@ -68,3 +70,13 @@ accessors!(get_rect_rotation, set_rect_rotation, RECT_ROTATION);
|
||||
accessors!(get_rect_chamfer1, set_rect_chamfer1, RECT_CHAMFER1);
|
||||
accessors!(get_rect_chamfer2, set_rect_chamfer2, RECT_CHAMFER2);
|
||||
accessors!(get_rect_fillet, set_rect_fillet, RECT_FILLET);
|
||||
accessors!(
|
||||
get_donut_inner_diameter,
|
||||
set_donut_inner_diameter,
|
||||
DONUT_INNER_DIAMETER
|
||||
);
|
||||
accessors!(
|
||||
get_donut_outer_diameter,
|
||||
set_donut_outer_diameter,
|
||||
DONUT_OUTER_DIAMETER
|
||||
);
|
||||
@@ -203,6 +203,7 @@ impl CadCommand for AttdefCommand {
|
||||
Some(WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
+159
-37
@@ -1,21 +1,19 @@
|
||||
// DONUT command — create a filled circular ring (thick LwPolyline).
|
||||
//
|
||||
// A donut is an LwPolyline with:
|
||||
// - 2 vertices at (cx ± r_avg, 0), both with bulge = 1.0 (two 180° CCW arcs)
|
||||
// - start_width = end_width = (outer - inner) / 2
|
||||
// - is_closed = true
|
||||
//
|
||||
// Workflow:
|
||||
// 1. Type inner diameter (or 0 for a filled circle)
|
||||
// 2. Type outer diameter
|
||||
// 3. Click center point(s); Enter to finish
|
||||
// DONUT creates a ring as a closed, constant-width LwPolyline.
|
||||
|
||||
use acadrust::entities::{LwPolyline, LwVertex};
|
||||
use acadrust::EntityType;
|
||||
use cadkernel::geom2d::{
|
||||
Circle as KernelCircle, Curve as KernelCurve, Vec2 as KernelVec2,
|
||||
};
|
||||
use glam::DVec3;
|
||||
|
||||
use crate::t;
|
||||
|
||||
use crate::command::{CadCommand, CmdResult, WorkingPlane};
|
||||
use crate::modules::draw::defaults;
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
|
||||
const TAU: f64 = std::f64::consts::TAU;
|
||||
|
||||
pub struct DonutCommand {
|
||||
state: DonutState,
|
||||
@@ -24,21 +22,64 @@ pub struct DonutCommand {
|
||||
plane: WorkingPlane,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum DonutState {
|
||||
AskInner,
|
||||
AskInnerSecond(DVec3),
|
||||
AskOuter,
|
||||
AskOuterSecond(DVec3),
|
||||
PlaceCenter,
|
||||
}
|
||||
|
||||
impl DonutCommand {
|
||||
pub fn new() -> Self {
|
||||
let mut inner_diameter = defaults::get_donut_inner_diameter();
|
||||
let mut outer_diameter = defaults::get_donut_outer_diameter();
|
||||
if inner_diameter > outer_diameter {
|
||||
std::mem::swap(&mut inner_diameter, &mut outer_diameter);
|
||||
}
|
||||
Self {
|
||||
state: DonutState::AskInner,
|
||||
inner_r: 0.0,
|
||||
outer_r: 1.0,
|
||||
inner_r: inner_diameter * 0.5,
|
||||
outer_r: outer_diameter * 0.5,
|
||||
plane: WorkingPlane::default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_inner_diameter(&mut self, diameter: f64) {
|
||||
self.inner_r = diameter * 0.5;
|
||||
self.state = DonutState::AskOuter;
|
||||
}
|
||||
|
||||
fn set_outer_diameter(&mut self, diameter: f64) {
|
||||
self.outer_r = diameter * 0.5;
|
||||
if self.inner_r > self.outer_r {
|
||||
std::mem::swap(&mut self.inner_r, &mut self.outer_r);
|
||||
}
|
||||
defaults::set_donut_inner_diameter(self.inner_r * 2.0);
|
||||
defaults::set_donut_outer_diameter(self.outer_r * 2.0);
|
||||
self.state = DonutState::PlaceCenter;
|
||||
}
|
||||
|
||||
fn point_distance(&self, first: DVec3, second: DVec3) -> f64 {
|
||||
let first = self.plane.to_local(first);
|
||||
let second = self.plane.to_local(second);
|
||||
KernelVec2::new(first.x, first.y).distance(KernelVec2::new(second.x, second.y))
|
||||
}
|
||||
|
||||
fn project_to_plane(&self, point: DVec3) -> DVec3 {
|
||||
let local = self.plane.to_local(point);
|
||||
self.plane.to_world(DVec3::new(local.x, local.y, 0.0))
|
||||
}
|
||||
}
|
||||
|
||||
fn prompt_with_default(prompt: &str, value: f64) -> String {
|
||||
match prompt.char_indices().next_back() {
|
||||
Some((index, suffix @ (':' | ':'))) => {
|
||||
format!("{} <{value:.4}>{suffix}", &prompt[..index])
|
||||
}
|
||||
_ => format!("{prompt} <{value:.4}>"),
|
||||
}
|
||||
}
|
||||
|
||||
impl CadCommand for DonutCommand {
|
||||
@@ -51,9 +92,19 @@ impl CadCommand for DonutCommand {
|
||||
}
|
||||
|
||||
fn prompt(&self) -> String {
|
||||
match &self.state {
|
||||
DonutState::AskInner => t!("DONUT Specify inside diameter <0>:").into_owned(),
|
||||
DonutState::AskOuter => t!("DONUT Specify outside diameter:").into_owned(),
|
||||
match self.state {
|
||||
DonutState::AskInner => t!("DONUT Specify inside diameter <0>:")
|
||||
.replace("<0>", &format!("<{:.4}>", self.inner_r * 2.0)),
|
||||
DonutState::AskInnerSecond(_) => {
|
||||
t!("DONUT Specify second point for inside diameter:").into_owned()
|
||||
}
|
||||
DonutState::AskOuter => prompt_with_default(
|
||||
t!("DONUT Specify outside diameter:").as_ref(),
|
||||
self.outer_r * 2.0,
|
||||
),
|
||||
DonutState::AskOuterSecond(_) => {
|
||||
t!("DONUT Specify second point for outside diameter:").into_owned()
|
||||
}
|
||||
DonutState::PlaceCenter => {
|
||||
t!("DONUT Specify center of donut (Enter to exit):").into_owned()
|
||||
}
|
||||
@@ -78,22 +129,20 @@ impl CadCommand for DonutCommand {
|
||||
.replace(',', ".")
|
||||
.parse()
|
||||
.ok()
|
||||
.filter(|&v: &f64| v >= 0.0)?;
|
||||
match &self.state {
|
||||
.filter(|v: &f64| v.is_finite())?;
|
||||
match self.state {
|
||||
DonutState::AskInner => {
|
||||
self.inner_r = val / 2.0;
|
||||
self.state = DonutState::AskOuter;
|
||||
if val < 0.0 {
|
||||
return Some(CmdResult::NeedPoint);
|
||||
}
|
||||
self.set_inner_diameter(val);
|
||||
Some(CmdResult::NeedPoint)
|
||||
}
|
||||
DonutState::AskOuter => {
|
||||
if val <= 0.0 {
|
||||
return None;
|
||||
return Some(CmdResult::NeedPoint);
|
||||
}
|
||||
self.outer_r = val / 2.0;
|
||||
if self.inner_r > self.outer_r {
|
||||
std::mem::swap(&mut self.inner_r, &mut self.outer_r);
|
||||
}
|
||||
self.state = DonutState::PlaceCenter;
|
||||
self.set_outer_diameter(val);
|
||||
Some(CmdResult::NeedPoint)
|
||||
}
|
||||
_ => None,
|
||||
@@ -101,29 +150,107 @@ impl CadCommand for DonutCommand {
|
||||
}
|
||||
|
||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||
match &self.state {
|
||||
match self.state {
|
||||
DonutState::AskInner => {
|
||||
self.state = DonutState::AskInnerSecond(self.project_to_plane(pt));
|
||||
CmdResult::NeedPoint
|
||||
}
|
||||
DonutState::AskInnerSecond(first) => {
|
||||
let diameter = self.point_distance(first, pt);
|
||||
if diameter <= 1.0e-9 {
|
||||
return CmdResult::NeedPoint;
|
||||
}
|
||||
self.set_inner_diameter(diameter);
|
||||
CmdResult::NeedPoint
|
||||
}
|
||||
DonutState::AskOuter => {
|
||||
self.state = DonutState::AskOuterSecond(self.project_to_plane(pt));
|
||||
CmdResult::NeedPoint
|
||||
}
|
||||
DonutState::AskOuterSecond(first) => {
|
||||
let diameter = self.point_distance(first, pt);
|
||||
if diameter <= 1.0e-9 {
|
||||
return CmdResult::NeedPoint;
|
||||
}
|
||||
self.set_outer_diameter(diameter);
|
||||
CmdResult::NeedPoint
|
||||
}
|
||||
DonutState::PlaceCenter => {
|
||||
let center = self.plane.to_local(pt);
|
||||
let entity = make_donut(center.x, center.y, center.z, self.inner_r, self.outer_r);
|
||||
// Keep command active so user can place more donuts.
|
||||
CmdResult::CommitEntity(self.plane.place_entity(entity))
|
||||
}
|
||||
_ => CmdResult::NeedPoint,
|
||||
}
|
||||
}
|
||||
|
||||
fn on_enter(&mut self) -> CmdResult {
|
||||
match &self.state {
|
||||
match self.state {
|
||||
DonutState::AskInner => {
|
||||
// Accept default 0 for inner diameter
|
||||
self.inner_r = 0.0;
|
||||
self.state = DonutState::AskOuter;
|
||||
CmdResult::NeedPoint
|
||||
}
|
||||
DonutState::AskOuter => {
|
||||
self.set_outer_diameter(self.outer_r * 2.0);
|
||||
CmdResult::NeedPoint
|
||||
}
|
||||
DonutState::PlaceCenter => CmdResult::Cancel,
|
||||
_ => CmdResult::Cancel,
|
||||
}
|
||||
}
|
||||
|
||||
fn on_mouse_move(&mut self, pt: DVec3) -> Option<WireModel> {
|
||||
match self.state {
|
||||
DonutState::AskInnerSecond(first) | DonutState::AskOuterSecond(first) => {
|
||||
let point = self.project_to_plane(pt);
|
||||
Some(WireModel::solid_f64(
|
||||
"rubber_band".into(),
|
||||
vec![first.to_array(), point.to_array()],
|
||||
WireModel::CYAN,
|
||||
false,
|
||||
))
|
||||
}
|
||||
DonutState::PlaceCenter => Some(donut_wire(
|
||||
pt,
|
||||
self.inner_r,
|
||||
self.outer_r,
|
||||
self.plane,
|
||||
)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn donut_wire(
|
||||
center: DVec3,
|
||||
inner_r: f64,
|
||||
outer_r: f64,
|
||||
plane: WorkingPlane,
|
||||
) -> WireModel {
|
||||
let local_center = plane.to_local(center);
|
||||
let mut points = Vec::new();
|
||||
for radius in [outer_r, inner_r] {
|
||||
if radius <= 1.0e-9 {
|
||||
continue;
|
||||
}
|
||||
if !points.is_empty() {
|
||||
points.push([f64::NAN; 3]);
|
||||
}
|
||||
points.extend(
|
||||
KernelCurve::Circle(KernelCircle {
|
||||
centre: [local_center.x, local_center.y],
|
||||
radius,
|
||||
})
|
||||
.tessellate_angle(TAU / 64.0)
|
||||
.into_iter()
|
||||
.map(|point| {
|
||||
plane
|
||||
.to_world(DVec3::new(point[0], point[1], local_center.z))
|
||||
.to_array()
|
||||
}),
|
||||
);
|
||||
}
|
||||
WireModel::solid_f64("rubber_band".into(), points, WireModel::CYAN, false)
|
||||
}
|
||||
|
||||
fn make_donut(cx: f64, cy: f64, elevation: f64, inner_r: f64, outer_r: f64) -> EntityType {
|
||||
@@ -136,17 +263,12 @@ fn make_donut(cx: f64, cy: f64, elevation: f64, inner_r: f64, outer_r: f64) -> E
|
||||
p.constant_width = width;
|
||||
p.elevation = elevation;
|
||||
|
||||
// Vertex at (cx - r, cy) with bulge 1.0 (180° CCW arc to next vertex)
|
||||
// Segment widths inherit the polyline's constant width.
|
||||
let mut v0 = LwVertex::new(Vector2::new(cx - r_avg, cy));
|
||||
v0.bulge = 1.0;
|
||||
v0.start_width = width;
|
||||
v0.end_width = width;
|
||||
|
||||
// Vertex at (cx + r, cy) with bulge 1.0 (second 180° arc back to v0)
|
||||
let mut v1 = LwVertex::new(Vector2::new(cx + r_avg, cy));
|
||||
v1.bulge = 1.0;
|
||||
v1.start_width = width;
|
||||
v1.end_width = width;
|
||||
|
||||
p.vertices = vec![v0, v1];
|
||||
EntityType::LwPolyline(p)
|
||||
|
||||
@@ -182,6 +182,7 @@ impl MlineCommand {
|
||||
Some(WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
@@ -125,6 +125,7 @@ impl CadCommand for ImageCommand {
|
||||
Some(WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
@@ -87,6 +87,7 @@ impl CadCommand for RayCommand {
|
||||
Some(WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
@@ -190,6 +191,7 @@ impl CadCommand for XLineCommand {
|
||||
Some(WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
@@ -364,6 +364,7 @@ impl CadCommand for AreaCommand {
|
||||
Some(WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
@@ -87,6 +87,7 @@ impl CadCommand for DistCommand {
|
||||
Some(WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
@@ -72,6 +72,7 @@ impl MeasureGeomCommand {
|
||||
WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
@@ -3721,6 +3721,7 @@ fn preview_wire(points: Vec<[f32; 3]>, color: [f32; 4], name: &str) -> WireModel
|
||||
WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
@@ -541,6 +541,7 @@ fn wire(name: &str, points: Vec<[f32; 3]>) -> WireModel {
|
||||
WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
@@ -56,6 +56,7 @@ impl CadCommand for PlotWindowCommand {
|
||||
Some(WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
@@ -138,6 +138,7 @@ impl CadCommand for ZoomWindowCommand {
|
||||
Some(WireModel {
|
||||
point_marker: None,
|
||||
taper_widths: Vec::new(),
|
||||
pattern_stations: Vec::new(),
|
||||
world_width: 0.0,
|
||||
depth_override: None,
|
||||
display_visible: true,
|
||||
|
||||
Reference in new issue
Block a user