mirror of
https://github.com/storytold/cadcraft.git
synced 2026-10-27 04:16:48 -06:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06c80c3734 | ||
|
|
d96aa15980 | ||
|
|
c108ee1662 |
@@ -120,7 +120,7 @@ fn style(s: &Session) -> String {
|
|||||||
s.doc().map(|d| d.header.str("DIMSTYLE", "Standard")).unwrap_or_else(|_| "Standard".into())
|
s.doc().map(|d| d.header.str("DIMSTYLE", "Standard")).unwrap_or_else(|_| "Standard".into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dim(s: &Session, kind: DimKind, defpt: Vec2, p13: Vec2, p14: Vec2, p15: Vec2, p16: Vec2, text: &str) -> EntityKind {
|
fn dim(s: &Session, kind: DimKind, defpt: Vec2, p13: Vec2, p14: Vec2, p15: Vec2, text: &str) -> EntityKind {
|
||||||
EntityKind::Dimension(Dimension {
|
EntityKind::Dimension(Dimension {
|
||||||
kind,
|
kind,
|
||||||
defpt: v3(defpt),
|
defpt: v3(defpt),
|
||||||
@@ -128,7 +128,7 @@ fn dim(s: &Session, kind: DimKind, defpt: Vec2, p13: Vec2, p14: Vec2, p15: Vec2,
|
|||||||
p13: v3(p13),
|
p13: v3(p13),
|
||||||
p14: v3(p14),
|
p14: v3(p14),
|
||||||
p15: v3(p15),
|
p15: v3(p15),
|
||||||
p16: v3(p16),
|
p16: v3(Vec2::ZERO),
|
||||||
text: text.into(),
|
text: text.into(),
|
||||||
style: style(s),
|
style: style(s),
|
||||||
measurement: 0.0,
|
measurement: 0.0,
|
||||||
@@ -205,7 +205,10 @@ fn angular_from_lines(s: &Session, h1: Handle, h2: Handle, at: Vec2) -> Option<E
|
|||||||
// The picked leg end goes last in each pair, so the renderer measures between p14 and p15.
|
// The picked leg end goes last in each pair, so the renderer measures between p14 and p15.
|
||||||
let (o1, t1) = if s1 == AssocSnap::Start { (a2, AssocSnap::End) } else { (a1, AssocSnap::Start) };
|
let (o1, t1) = if s1 == AssocSnap::Start { (a2, AssocSnap::End) } else { (a1, AssocSnap::Start) };
|
||||||
let (o2, t2) = if s2 == AssocSnap::Start { (b2, AssocSnap::End) } else { (b1, AssocSnap::Start) };
|
let (o2, t2) = if s2 == AssocSnap::Start { (b2, AssocSnap::End) } else { (b1, AssocSnap::Start) };
|
||||||
let k = dim(s, DimKind::Angular, o2, o1, p1, p2, at, "");
|
let mut k = dim(s, DimKind::Angular, o2, o1, p1, p2, "");
|
||||||
|
if let EntityKind::Dimension(d) = &mut k {
|
||||||
|
d.p16 = v3(at);
|
||||||
|
}
|
||||||
let mut assoc = Vec::new();
|
let mut assoc = Vec::new();
|
||||||
if assoc_enabled(s) {
|
if assoc_enabled(s) {
|
||||||
assoc = vec![
|
assoc = vec![
|
||||||
@@ -225,7 +228,7 @@ fn run_linear(s: &mut Session, p: &Value) -> Result<Value> {
|
|||||||
};
|
};
|
||||||
let at = point_req("dimlinear", p, "at")?;
|
let at = point_req("dimlinear", p, "at")?;
|
||||||
let rot = p.get("rotation").and_then(Value::as_f64).map(f64::to_radians);
|
let rot = p.get("rotation").and_then(Value::as_f64).map(f64::to_radians);
|
||||||
let k = dim(s, linear_kind(a, b, at, rot, false), at, a, b, Vec2::ZERO, Vec2::ZERO, str_param(p, "text").unwrap_or(""));
|
let k = dim(s, linear_kind(a, b, at, rot, false), at, a, b, Vec2::ZERO, str_param(p, "text").unwrap_or(""));
|
||||||
Ok(json!({ "handle": add_dim(s, k)?.hex() }))
|
Ok(json!({ "handle": add_dim(s, k)?.hex() }))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,7 +236,7 @@ fn run_aligned(s: &mut Session, p: &Value) -> Result<Value> {
|
|||||||
let a = point_req("dimaligned", p, "p1")?;
|
let a = point_req("dimaligned", p, "p1")?;
|
||||||
let b = point_req("dimaligned", p, "p2")?;
|
let b = point_req("dimaligned", p, "p2")?;
|
||||||
let at = point_req("dimaligned", p, "at")?;
|
let at = point_req("dimaligned", p, "at")?;
|
||||||
let k = dim(s, DimKind::Aligned, at, a, b, Vec2::ZERO, Vec2::ZERO, str_param(p, "text").unwrap_or(""));
|
let k = dim(s, DimKind::Aligned, at, a, b, Vec2::ZERO, str_param(p, "text").unwrap_or(""));
|
||||||
Ok(json!({ "handle": add_dim(s, k)?.hex() }))
|
Ok(json!({ "handle": add_dim(s, k)?.hex() }))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,9 +264,9 @@ fn radial(s: &mut Session, p: &Value, diameter: bool) -> Result<Value> {
|
|||||||
return Err(bad(id, "`point` must differ from `center`"));
|
return Err(bad(id, "`point` must differ from `center`"));
|
||||||
}
|
}
|
||||||
let k = if diameter {
|
let k = if diameter {
|
||||||
dim(s, DimKind::Diameter, c + (c - pt), Vec2::ZERO, Vec2::ZERO, pt, Vec2::ZERO, "")
|
dim(s, DimKind::Diameter, c + (c - pt), Vec2::ZERO, Vec2::ZERO, pt, "")
|
||||||
} else {
|
} else {
|
||||||
dim(s, DimKind::Radius, c, Vec2::ZERO, Vec2::ZERO, pt, Vec2::ZERO, "")
|
dim(s, DimKind::Radius, c, Vec2::ZERO, Vec2::ZERO, pt, "")
|
||||||
};
|
};
|
||||||
let k = match at {
|
let k = match at {
|
||||||
Some(at) => text_at(k, at),
|
Some(at) => text_at(k, at),
|
||||||
@@ -308,7 +311,7 @@ fn run_angular(s: &mut Session, p: &Value) -> Result<Value> {
|
|||||||
_ => return Err(bad("dimangular", "object is not an arc")),
|
_ => return Err(bad("dimangular", "object is not an arc")),
|
||||||
};
|
};
|
||||||
let g = cadcraft_geom::Arc::new(a.center.xy(), a.radius, a.start, a.end);
|
let g = cadcraft_geom::Arc::new(a.center.xy(), a.radius, a.start, a.end);
|
||||||
let k = dim(s, DimKind::Angular3P, at, g.start_point(), g.end_point(), g.center, Vec2::ZERO, "");
|
let k = dim(s, DimKind::Angular3P, at, g.start_point(), g.end_point(), g.center, "");
|
||||||
return Ok(json!({ "handle": add_dim(s, k)?.hex() }));
|
return Ok(json!({ "handle": add_dim(s, k)?.hex() }));
|
||||||
}
|
}
|
||||||
let v = point_req("dimangular", p, "vertex")?;
|
let v = point_req("dimangular", p, "vertex")?;
|
||||||
@@ -318,7 +321,7 @@ fn run_angular(s: &mut Session, p: &Value) -> Result<Value> {
|
|||||||
if v.near(a, 1e-12) || v.near(b, 1e-12) {
|
if v.near(a, 1e-12) || v.near(b, 1e-12) {
|
||||||
return Err(bad("dimangular", "`p1` and `p2` must differ from `vertex`"));
|
return Err(bad("dimangular", "`p1` and `p2` must differ from `vertex`"));
|
||||||
}
|
}
|
||||||
let k = dim(s, DimKind::Angular3P, at, a, b, v, Vec2::ZERO, "");
|
let k = dim(s, DimKind::Angular3P, at, a, b, v, "");
|
||||||
Ok(json!({ "handle": add_dim(s, k)?.hex() }))
|
Ok(json!({ "handle": add_dim(s, k)?.hex() }))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,7 +333,7 @@ fn run_arclen(s: &mut Session, p: &Value) -> Result<Value> {
|
|||||||
_ => return Err(bad("dimarc", "object is not an arc")),
|
_ => return Err(bad("dimarc", "object is not an arc")),
|
||||||
};
|
};
|
||||||
let ga = cadcraft_geom::Arc::new(a.center.xy(), a.radius, a.start, a.end);
|
let ga = cadcraft_geom::Arc::new(a.center.xy(), a.radius, a.start, a.end);
|
||||||
let k = dim(s, DimKind::ArcLength, at, ga.start_point(), ga.end_point(), ga.center, Vec2::ZERO, "");
|
let k = dim(s, DimKind::ArcLength, at, ga.start_point(), ga.end_point(), ga.center, "");
|
||||||
Ok(json!({ "handle": add_dim(s, k)?.hex() }))
|
Ok(json!({ "handle": add_dim(s, k)?.hex() }))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,7 +341,7 @@ fn run_ordinate(s: &mut Session, p: &Value) -> Result<Value> {
|
|||||||
let f = point_req("dimordinate", p, "feature")?;
|
let f = point_req("dimordinate", p, "feature")?;
|
||||||
let l = point_req("dimordinate", p, "leader")?;
|
let l = point_req("dimordinate", p, "leader")?;
|
||||||
let xtype = p.get("xtype").and_then(Value::as_bool).unwrap_or((l - f).y.abs() > (l - f).x.abs());
|
let xtype = p.get("xtype").and_then(Value::as_bool).unwrap_or((l - f).y.abs() > (l - f).x.abs());
|
||||||
let k = dim(s, DimKind::Ordinate { x_type: xtype }, Vec2::ZERO, f, l, Vec2::ZERO, Vec2::ZERO, "");
|
let k = dim(s, DimKind::Ordinate { x_type: xtype }, Vec2::ZERO, f, l, Vec2::ZERO, "");
|
||||||
Ok(json!({ "handle": add_dim(s, k)?.hex() }))
|
Ok(json!({ "handle": add_dim(s, k)?.hex() }))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1060,7 +1063,7 @@ impl Interactive for LinearM {
|
|||||||
}
|
}
|
||||||
(_, Input::Point(at)) => {
|
(_, Input::Point(at)) => {
|
||||||
let (Some(&a), Some(&b)) = (self.pts.first(), self.pts.get(1)) else { return Ok(Step::Continue) };
|
let (Some(&a), Some(&b)) = (self.pts.first(), self.pts.get(1)) else { return Ok(Step::Continue) };
|
||||||
let k = self.text.apply(dim(s, linear_kind(a, b, at, self.rotation, self.aligned), at, a, b, Vec2::ZERO, Vec2::ZERO, ""));
|
let k = self.text.apply(dim(s, linear_kind(a, b, at, self.rotation, self.aligned), at, a, b, Vec2::ZERO, ""));
|
||||||
add_dim(s, k)?;
|
add_dim(s, k)?;
|
||||||
if let Some(EntityKind::Dimension(d)) = s.last_dim.and_then(|h| s.doc().ok()?.entity(h).map(|e| e.kind.clone())) {
|
if let Some(EntityKind::Dimension(d)) = s.last_dim.and_then(|h| s.doc().ok()?.entity(h).map(|e| e.kind.clone())) {
|
||||||
let st = s.doc()?.dim_style(&d.style).cloned().unwrap_or_default();
|
let st = s.doc()?.dim_style(&d.style).cloned().unwrap_or_default();
|
||||||
@@ -1087,7 +1090,7 @@ impl Interactive for LinearM {
|
|||||||
fn preview(&self, s: &Session, c: Vec2) -> Vec<EntityKind> {
|
fn preview(&self, s: &Session, c: Vec2) -> Vec<EntityKind> {
|
||||||
match self.pts.as_slice() {
|
match self.pts.as_slice() {
|
||||||
[a] => vec![super::helpers::line(*a, c)],
|
[a] => vec![super::helpers::line(*a, c)],
|
||||||
[a, b] => vec![self.text.apply(dim(s, linear_kind(*a, *b, c, self.rotation, self.aligned), c, *a, *b, Vec2::ZERO, Vec2::ZERO, ""))],
|
[a, b] => vec![self.text.apply(dim(s, linear_kind(*a, *b, c, self.rotation, self.aligned), c, *a, *b, Vec2::ZERO, ""))],
|
||||||
_ => Vec::new(),
|
_ => Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1106,9 +1109,9 @@ impl RadialM {
|
|||||||
fn kind(&self, s: &Session, c: Vec2, r: f64, at: Vec2) -> EntityKind {
|
fn kind(&self, s: &Session, c: Vec2, r: f64, at: Vec2) -> EntityKind {
|
||||||
let pt = c + (at - c).normalized() * r;
|
let pt = c + (at - c).normalized() * r;
|
||||||
let k = self.text.apply(if self.diameter {
|
let k = self.text.apply(if self.diameter {
|
||||||
dim(s, DimKind::Diameter, c + (c - pt), Vec2::ZERO, Vec2::ZERO, pt, Vec2::ZERO, "")
|
dim(s, DimKind::Diameter, c + (c - pt), Vec2::ZERO, Vec2::ZERO, pt, "")
|
||||||
} else {
|
} else {
|
||||||
dim(s, DimKind::Radius, c, Vec2::ZERO, Vec2::ZERO, pt, Vec2::ZERO, "")
|
dim(s, DimKind::Radius, c, Vec2::ZERO, Vec2::ZERO, pt, "")
|
||||||
});
|
});
|
||||||
text_at(k, at)
|
text_at(k, at)
|
||||||
}
|
}
|
||||||
@@ -1241,7 +1244,7 @@ impl Interactive for AngularM {
|
|||||||
([h1, h2], None) => angular_from_lines(s, *h1, *h2, at),
|
([h1, h2], None) => angular_from_lines(s, *h1, *h2, at),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
let k = k.unwrap_or_else(|| dim(s, DimKind::Angular3P, at, a, b, v, Vec2::ZERO, ""));
|
let k = k.unwrap_or_else(|| dim(s, DimKind::Angular3P, at, a, b, v, ""));
|
||||||
add_dim(s, self.text.apply(k))?;
|
add_dim(s, self.text.apply(k))?;
|
||||||
Ok(Step::Done)
|
Ok(Step::Done)
|
||||||
}
|
}
|
||||||
@@ -1307,9 +1310,7 @@ impl Interactive for AngularM {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn preview(&self, s: &Session, c: Vec2) -> Vec<EntityKind> {
|
fn preview(&self, s: &Session, c: Vec2) -> Vec<EntityKind> {
|
||||||
self.geometry()
|
self.geometry().map(|(v, a, b)| vec![self.text.apply(dim(s, DimKind::Angular3P, self.located(v, c), a, b, v, ""))]).unwrap_or_default()
|
||||||
.map(|(v, a, b)| vec![self.text.apply(dim(s, DimKind::Angular3P, self.located(v, c), a, b, v, Vec2::ZERO, ""))])
|
|
||||||
.unwrap_or_default()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1385,7 +1386,7 @@ impl Interactive for ArcLenM {
|
|||||||
Ok(Step::Continue)
|
Ok(Step::Continue)
|
||||||
}
|
}
|
||||||
(Some(g), Input::Point(at)) => {
|
(Some(g), Input::Point(at)) => {
|
||||||
add_dim(s, self.text.apply(dim(s, DimKind::ArcLength, at, g.start_point(), g.end_point(), g.center, Vec2::ZERO, "")))?;
|
add_dim(s, self.text.apply(dim(s, DimKind::ArcLength, at, g.start_point(), g.end_point(), g.center, "")))?;
|
||||||
Ok(Step::Done)
|
Ok(Step::Done)
|
||||||
}
|
}
|
||||||
(Some(_), Input::Keyword(k)) => {
|
(Some(_), Input::Keyword(k)) => {
|
||||||
@@ -1404,9 +1405,7 @@ impl Interactive for ArcLenM {
|
|||||||
if self.partial.is_some() {
|
if self.partial.is_some() {
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
}
|
}
|
||||||
self.arc
|
self.arc.map(|g| vec![self.text.apply(dim(s, DimKind::ArcLength, c, g.start_point(), g.end_point(), g.center, ""))]).unwrap_or_default()
|
||||||
.map(|g| vec![self.text.apply(dim(s, DimKind::ArcLength, c, g.start_point(), g.end_point(), g.center, Vec2::ZERO, ""))])
|
|
||||||
.unwrap_or_default()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1421,7 +1420,7 @@ struct OrdinateM {
|
|||||||
impl OrdinateM {
|
impl OrdinateM {
|
||||||
fn kind(&self, s: &Session, f: Vec2, l: Vec2) -> EntityKind {
|
fn kind(&self, s: &Session, f: Vec2, l: Vec2) -> EntityKind {
|
||||||
let x = self.xtype.unwrap_or((l - f).y.abs() > (l - f).x.abs());
|
let x = self.xtype.unwrap_or((l - f).y.abs() > (l - f).x.abs());
|
||||||
self.text.apply(dim(s, DimKind::Ordinate { x_type: x }, Vec2::ZERO, f, l, Vec2::ZERO, Vec2::ZERO, ""))
|
self.text.apply(dim(s, DimKind::Ordinate { x_type: x }, Vec2::ZERO, f, l, Vec2::ZERO, ""))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -283,7 +283,7 @@ fn jogged_kind(s: &Session, c: Vec2, r: f64, center: Vec2, at: Vec2, jog: Option
|
|||||||
}
|
}
|
||||||
let tip = c + dir * r;
|
let tip = c + dir * r;
|
||||||
let jog = jog.unwrap_or_else(|| center.mid(tip));
|
let jog = jog.unwrap_or_else(|| center.mid(tip));
|
||||||
let mut k = dim(s, DimKind::Radius, c, Vec2::ZERO, Vec2::ZERO, tip, Vec2::ZERO, text);
|
let mut k = dim(s, DimKind::Radius, c, Vec2::ZERO, Vec2::ZERO, tip, text);
|
||||||
if let EntityKind::Dimension(dm) = &mut k {
|
if let EntityKind::Dimension(dm) = &mut k {
|
||||||
dm.marks.jogged = Some(JoggedRadius { center: v3(center), jog: v3(jog) });
|
dm.marks.jogged = Some(JoggedRadius { center: v3(center), jog: v3(jog) });
|
||||||
if at.dist(c) > r + 1e-9 {
|
if at.dist(c) > r + 1e-9 {
|
||||||
|
|||||||
@@ -96,9 +96,9 @@ fn plan(
|
|||||||
let dir = if dir == Vec2::ZERO || !dir.is_finite() { Vec2::from_angle(std::f64::consts::FRAC_PI_4) } else { dir };
|
let dir = if dir == Vec2::ZERO || !dir.is_finite() { Vec2::from_angle(std::f64::consts::FRAC_PI_4) } else { dir };
|
||||||
let p = *c + dir * *r;
|
let p = *c + dir * *r;
|
||||||
out.push(if mode == Mode::Diameter {
|
out.push(if mode == Mode::Diameter {
|
||||||
dim(s, DimKind::Diameter, *c - dir * *r, Vec2::ZERO, Vec2::ZERO, p, Vec2::ZERO, "")
|
dim(s, DimKind::Diameter, *c - dir * *r, Vec2::ZERO, Vec2::ZERO, p, "")
|
||||||
} else {
|
} else {
|
||||||
dim(s, DimKind::Radius, *c, Vec2::ZERO, Vec2::ZERO, p, Vec2::ZERO, "")
|
dim(s, DimKind::Radius, *c, Vec2::ZERO, Vec2::ZERO, p, "")
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if out.is_empty() {
|
if out.is_empty() {
|
||||||
@@ -131,7 +131,7 @@ fn plan(
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|p| {
|
.map(|p| {
|
||||||
let end = if vertical { Vec2::new(at.x, p.y) } else { Vec2::new(p.x, at.y) };
|
let end = if vertical { Vec2::new(at.x, p.y) } else { Vec2::new(p.x, at.y) };
|
||||||
dim(s, DimKind::Ordinate { x_type: !vertical }, origin, *p, end, Vec2::ZERO, Vec2::ZERO, "")
|
dim(s, DimKind::Ordinate { x_type: !vertical }, origin, *p, end, Vec2::ZERO, "")
|
||||||
})
|
})
|
||||||
.collect());
|
.collect());
|
||||||
}
|
}
|
||||||
@@ -147,8 +147,7 @@ fn plan(
|
|||||||
let mid = bounds.center();
|
let mid = bounds.center();
|
||||||
let out_dir =
|
let out_dir =
|
||||||
if vertical { Vec2::new(if at.x >= mid.x { 1.0 } else { -1.0 }, 0.0) } else { Vec2::new(0.0, if at.y >= mid.y { 1.0 } else { -1.0 }) };
|
if vertical { Vec2::new(if at.x >= mid.x { 1.0 } else { -1.0 }, 0.0) } else { Vec2::new(0.0, if at.y >= mid.y { 1.0 } else { -1.0 }) };
|
||||||
let lin =
|
let lin = |a: Vec2, b: Vec2, k: usize| dim(s, DimKind::Linear { rotation: rot }, at + out_dir * (step * k as f64), a, b, Vec2::ZERO, "");
|
||||||
|a: Vec2, b: Vec2, k: usize| dim(s, DimKind::Linear { rotation: rot }, at + out_dir * (step * k as f64), a, b, Vec2::ZERO, Vec2::ZERO, "");
|
|
||||||
Ok(match mode {
|
Ok(match mode {
|
||||||
Mode::Baseline => {
|
Mode::Baseline => {
|
||||||
// From the datum (the point nearest it, by default the first) to every other point.
|
// From the datum (the point nearest it, by default the first) to every other point.
|
||||||
|
|||||||
@@ -1572,7 +1572,7 @@ impl Interactive for XlineM2 {
|
|||||||
// RECTANG with Area / Dimensions / Rotation / Width / Elevation / Thickness
|
// RECTANG with Area / Dimensions / Rotation / Width / Elevation / Thickness
|
||||||
// =====================================================================================
|
// =====================================================================================
|
||||||
|
|
||||||
fn rect_kind(first: Vec2, w: f64, h: f64, rot: f64, fillet: f64, chamfer: (f64, f64), width: f64, elevation: f64) -> EntityKind {
|
fn rect_kind(first: Vec2, (w, h): (f64, f64), rot: f64, fillet: f64, chamfer: (f64, f64), width: f64, elevation: f64) -> EntityKind {
|
||||||
let local = rect_with_corners(Vec2::ZERO, Vec2::new(w, h), fillet, chamfer);
|
let local = rect_with_corners(Vec2::ZERO, Vec2::new(w, h), fillet, chamfer);
|
||||||
let vs = local.into_iter().map(|v| PolyVertex { p: first + v.p.rotate(rot), ..v }).collect();
|
let vs = local.into_iter().map(|v| PolyVertex { p: first + v.p.rotate(rot), ..v }).collect();
|
||||||
let mut k = lwpoly(vs, true);
|
let mut k = lwpoly(vs, true);
|
||||||
@@ -1631,7 +1631,7 @@ pub(crate) fn run_rectang2(s: &mut Session, p: &Value) -> Result<Value> {
|
|||||||
return Err(bad("rectang", "rectangle has no area"));
|
return Err(bad("rectang", "rectangle has no area"));
|
||||||
}
|
}
|
||||||
let first = if centered { a - Vec2::new(w / 2.0, h / 2.0).rotate(rot) } else { a };
|
let first = if centered { a - Vec2::new(w / 2.0, h / 2.0).rotate(rot) } else { a };
|
||||||
let k = rect_kind(first, w, h, rot, fillet, ch, width, f64_or(p, "elevation", 0.0));
|
let k = rect_kind(first, (w, h), rot, fillet, ch, width, f64_or(p, "elevation", 0.0));
|
||||||
let hd = s.add_entity(k)?;
|
let hd = s.add_entity(k)?;
|
||||||
// A rectangle has its own thickness option and does not take THICKNESS.
|
// A rectangle has its own thickness option and does not take THICKNESS.
|
||||||
let th = f64_or(p, "thickness", 0.0);
|
let th = f64_or(p, "thickness", 0.0);
|
||||||
@@ -1683,7 +1683,8 @@ impl RectM2 {
|
|||||||
return Err(other("The rectangle has no area."));
|
return Err(other("The rectangle has no area."));
|
||||||
}
|
}
|
||||||
let first = self.origin(w, h).unwrap_or(a);
|
let first = self.origin(w, h).unwrap_or(a);
|
||||||
let hd = s.add_entity(rect_kind(first, w, h, self.rotation, self.fillet, self.chamfer, self.width, self.elevation))?;
|
let hd = s.add_entity(rect_kind(first, (w, h), self.rotation, self.fillet, self.chamfer, self.width, self.elevation))?;
|
||||||
|
// A rectangle has its own thickness option and does not take THICKNESS.
|
||||||
let t = self.thickness;
|
let t = self.thickness;
|
||||||
s.doc_mut()?.modify_entity(hd, |e| e.common.thickness = t)?;
|
s.doc_mut()?.modify_entity(hd, |e| e.common.thickness = t)?;
|
||||||
Ok(Step::Done)
|
Ok(Step::Done)
|
||||||
@@ -1861,7 +1862,7 @@ impl Interactive for RectM2 {
|
|||||||
}
|
}
|
||||||
match self.other_corner(c).and_then(|(w, h)| self.origin(w, h).map(|a| (a, w, h))) {
|
match self.other_corner(c).and_then(|(w, h)| self.origin(w, h).map(|a| (a, w, h))) {
|
||||||
Some((a, w, h)) if w.abs() > 1e-12 && h.abs() > 1e-12 => {
|
Some((a, w, h)) if w.abs() > 1e-12 && h.abs() > 1e-12 => {
|
||||||
vec![rect_kind(a, w, h, self.rotation, self.fillet, self.chamfer, self.width, self.elevation)]
|
vec![rect_kind(a, (w, h), self.rotation, self.fillet, self.chamfer, self.width, self.elevation)]
|
||||||
}
|
}
|
||||||
_ => Vec::new(),
|
_ => Vec::new(),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -280,11 +280,9 @@ impl Unused {
|
|||||||
fn item_json(
|
fn item_json(
|
||||||
c: Category,
|
c: Category,
|
||||||
name: &str,
|
name: &str,
|
||||||
entities: usize,
|
(entities, block_entities): (usize, usize),
|
||||||
block_entities: usize,
|
|
||||||
references: usize,
|
references: usize,
|
||||||
used: bool,
|
(used, empty): (bool, bool),
|
||||||
empty: bool,
|
|
||||||
current: Option<bool>,
|
current: Option<bool>,
|
||||||
unused: &Unused,
|
unused: &Unused,
|
||||||
) -> Value {
|
) -> Value {
|
||||||
@@ -314,13 +312,13 @@ fn items(scan: &Scan, unused: &Unused, d: &Drawing) -> Vec<Value> {
|
|||||||
let (e, b) = scan.layers.get(&l.name.to_ascii_lowercase()).copied().unwrap_or_default();
|
let (e, b) = scan.layers.get(&l.name.to_ascii_lowercase()).copied().unwrap_or_default();
|
||||||
let uses = e.saturating_add(b);
|
let uses = e.saturating_add(b);
|
||||||
let cur = l.name.eq_ignore_ascii_case(¤t_layer);
|
let cur = l.name.eq_ignore_ascii_case(¤t_layer);
|
||||||
out.push(item_json(Category::Layer, &l.name, e, b, 0, uses > 0, uses == 0, Some(cur), unused));
|
out.push(item_json(Category::Layer, &l.name, (e, b), 0, (uses > 0, uses == 0), Some(cur), unused));
|
||||||
}
|
}
|
||||||
for b in d.blocks.values() {
|
for b in d.blocks.values() {
|
||||||
let (e, n) = scan.blocks.get(&b.name.to_ascii_lowercase()).copied().unwrap_or_default();
|
let (e, n) = scan.blocks.get(&b.name.to_ascii_lowercase()).copied().unwrap_or_default();
|
||||||
// A definition is used when a reference to it is reachable, as PURGE counts it.
|
// A definition is used when a reference to it is reachable, as PURGE counts it.
|
||||||
let used = scan.used_blocks.contains(&b.name.to_ascii_uppercase());
|
let used = scan.used_blocks.contains(&b.name.to_ascii_uppercase());
|
||||||
out.push(item_json(Category::Block, &b.name, e, n, 0, used, e.saturating_add(n) == 0, None, unused));
|
out.push(item_json(Category::Block, &b.name, (e, n), 0, (used, e.saturating_add(n) == 0), None, unused));
|
||||||
}
|
}
|
||||||
let current_style = d.header.str("TEXTSTYLE", "Standard");
|
let current_style = d.header.str("TEXTSTYLE", "Standard");
|
||||||
for t in &d.text_styles {
|
for t in &d.text_styles {
|
||||||
@@ -328,7 +326,7 @@ fn items(scan: &Scan, unused: &Unused, d: &Drawing) -> Vec<Value> {
|
|||||||
let r = scan.style_refs.get(&t.name.to_ascii_lowercase()).copied().unwrap_or(0);
|
let r = scan.style_refs.get(&t.name.to_ascii_lowercase()).copied().unwrap_or(0);
|
||||||
let uses = e.saturating_add(b).saturating_add(r);
|
let uses = e.saturating_add(b).saturating_add(r);
|
||||||
let cur = t.name.eq_ignore_ascii_case(¤t_style);
|
let cur = t.name.eq_ignore_ascii_case(¤t_style);
|
||||||
out.push(item_json(Category::TextStyle, &t.name, e, b, r, uses > 0, uses == 0, Some(cur), unused));
|
out.push(item_json(Category::TextStyle, &t.name, (e, b), r, (uses > 0, uses == 0), Some(cur), unused));
|
||||||
}
|
}
|
||||||
let current_linetype = d.header.str("CELTYPE", "ByLayer");
|
let current_linetype = d.header.str("CELTYPE", "ByLayer");
|
||||||
for t in &d.linetypes {
|
for t in &d.linetypes {
|
||||||
@@ -336,7 +334,7 @@ fn items(scan: &Scan, unused: &Unused, d: &Drawing) -> Vec<Value> {
|
|||||||
let r = scan.linetype_refs.get(&t.name.to_ascii_lowercase()).copied().unwrap_or(0);
|
let r = scan.linetype_refs.get(&t.name.to_ascii_lowercase()).copied().unwrap_or(0);
|
||||||
let uses = e.saturating_add(b).saturating_add(r);
|
let uses = e.saturating_add(b).saturating_add(r);
|
||||||
let cur = t.name.eq_ignore_ascii_case(¤t_linetype);
|
let cur = t.name.eq_ignore_ascii_case(¤t_linetype);
|
||||||
out.push(item_json(Category::Linetype, &t.name, e, b, r, uses > 0, uses == 0, Some(cur), unused));
|
out.push(item_json(Category::Linetype, &t.name, (e, b), r, (uses > 0, uses == 0), Some(cur), unused));
|
||||||
}
|
}
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,8 +80,7 @@ fn same_polyline(
|
|||||||
s: &mut Session,
|
s: &mut Session,
|
||||||
h: Handle,
|
h: Handle,
|
||||||
pl: &LwPolyline,
|
pl: &LwPolyline,
|
||||||
p1: Vec2,
|
(p1, p2): (Vec2, Vec2),
|
||||||
p2: Vec2,
|
|
||||||
r: f64,
|
r: f64,
|
||||||
chamfer: Option<ChamferDistances>,
|
chamfer: Option<ChamferDistances>,
|
||||||
trim: bool,
|
trim: bool,
|
||||||
@@ -223,7 +222,7 @@ pub(crate) fn fillet_pline(
|
|||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
let made = match (&e1.kind, &e2.kind) {
|
let made = match (&e1.kind, &e2.kind) {
|
||||||
(EntityKind::LwPolyline(pl), _) if h1 == h2 => same_polyline(s, h1, pl, p1, p2, r, chamfer, trim)?,
|
(EntityKind::LwPolyline(pl), _) if h1 == h2 => same_polyline(s, h1, pl, (p1, p2), r, chamfer, trim)?,
|
||||||
(EntityKind::LwPolyline(pl), k) if as_line(k).is_some() => {
|
(EntityKind::LwPolyline(pl), k) if as_line(k).is_some() => {
|
||||||
let ln = as_line(k).ok_or_else(|| other("Select a line."))?;
|
let ln = as_line(k).ok_or_else(|| other("Select a line."))?;
|
||||||
polyline_and_line(s, (h1, pl, p1), (h2, ln, p2), true, r, chamfer, trim)?
|
polyline_and_line(s, (h1, pl, p1), (h2, ln, p2), true, r, chamfer, trim)?
|
||||||
|
|||||||
@@ -528,14 +528,14 @@ impl Family<'_> {
|
|||||||
if solid_line {
|
if solid_line {
|
||||||
out.push(vec![self.to_world(Vec2::new(x0, y)), self.to_world(Vec2::new(x1, y))]);
|
out.push(vec![self.to_world(Vec2::new(x0, y)), self.to_world(Vec2::new(x1, y))]);
|
||||||
} else {
|
} else {
|
||||||
self.dash(x0, x1, y, offset, pat_len, out, work);
|
self.dash((x0, x1), y, offset, pat_len, out, work);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The dashes and dots of the span `x0..x1` of the line at `y`, phase anchored at x = `offset`.
|
/// The dashes and dots of the span `x0..x1` of the line at `y`, phase anchored at x = `offset`.
|
||||||
fn dash(&self, x0: f64, x1: f64, y: f64, offset: f64, pat_len: f64, out: &mut Vec<Vec<Vec2>>, work: &mut u64) {
|
fn dash(&self, (x0, x1): (f64, f64), y: f64, offset: f64, pat_len: f64, out: &mut Vec<Vec<Vec2>>, work: &mut u64) {
|
||||||
let start_rep = ((x0 - offset) / pat_len).floor();
|
let start_rep = ((x0 - offset) / pat_len).floor();
|
||||||
let mut x = offset + start_rep * pat_len;
|
let mut x = offset + start_rep * pat_len;
|
||||||
let mut guard = 0;
|
let mut guard = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user