mirror of
https://github.com/storytold/cadcraft.git
synced 2026-11-09 12:00:50 -06:00
View twist: read and write every twist within one turn, so #2022's hostile-angle checks hold
A twist of -1e-20 degrees read as a full turn (2π), and a huge twist set from JSON or MCP was written as a huge angle. Readers and writers of VIEWPORT 51, VPORT 51 and VIEW 50 now go through norm_angle.
This commit is contained in:
@@ -245,7 +245,7 @@ pub(super) fn entity_with_table_budget(kind: &str, tags: &[Tag], table_cells_lef
|
||||
"ACAD_TABLE" => EntityKind::Table(acad_table(tags, table_cells_left)),
|
||||
"VIEWPORT" => EntityKind::Viewport({
|
||||
// View twist (group 51, degrees).
|
||||
let twist = t.f(51).filter(|a| a.is_finite()).map_or(0.0, |a| a.rem_euclid(360.0).to_radians());
|
||||
let twist = t.f(51).map_or(0.0, |a| cadcraft_geom::norm_angle(a.to_radians()));
|
||||
Viewport {
|
||||
center: t.p(10),
|
||||
width: t.fd(40, 1.0),
|
||||
|
||||
@@ -224,7 +224,7 @@ pub(super) fn tables(tags: &[Tag], d: &mut Drawing, rx: &mut Rx) {
|
||||
if name.is_empty() || !(h.is_finite() && w.is_finite() && h > 0.0 && w > 0.0) || d.views.len() >= MAX_OBJECTS {
|
||||
continue;
|
||||
}
|
||||
let twist = t.f(50).filter(|a| a.is_finite()).map_or(0.0, |a| a.rem_euclid(360.0).to_radians());
|
||||
let twist = t.f(50).map_or(0.0, |a| cadcraft_geom::norm_angle(a.to_radians()));
|
||||
// The view centre 10/20 is in display coordinates, whose origin is the target 12/22/32.
|
||||
let center = t.view_center(10, 12, twist);
|
||||
if !(center.x.is_finite() && center.y.is_finite()) {
|
||||
@@ -326,7 +326,7 @@ const MAX_VPORT_TILES: usize = 64;
|
||||
fn vport_record(d: &mut Drawing, t: &T) {
|
||||
let name = t.s(2).map(|n| n.trim().to_string()).unwrap_or_default();
|
||||
// View twist (group 51, degrees).
|
||||
let twist = t.f(51).filter(|a| a.is_finite()).map_or(0.0, |a| a.rem_euclid(360.0).to_radians());
|
||||
let twist = t.f(51).map_or(0.0, |a| cadcraft_geom::norm_angle(a.to_radians()));
|
||||
// The view centre 12/22 is in display coordinates, whose origin is the view target 17/27/37.
|
||||
let (min, max, center) = (t.p(10).xy(), t.p(11).xy(), t.view_center(12, 17, twist));
|
||||
let height = t.fd(40, 0.0);
|
||||
|
||||
@@ -684,12 +684,14 @@ fn write_viewport_entity(w: &mut W, d: &Drawing, e: &Entity, owner: &str, paper:
|
||||
// Status 68: a positive value is "on" (the stacking order; 1 is the active viewport), 0 off.
|
||||
w.i(68, if v.on { i64::from(v.id.clamp(1, 32767)) } else { 0 });
|
||||
w.i(69, i64::from(v.id));
|
||||
// Within one turn, so a hostile twist (from JSON or MCP) writes a sane angle.
|
||||
let twist = cadcraft_geom::norm_angle(v.view_twist());
|
||||
// The view centre in display coordinates (turned by the twist).
|
||||
w.p2(12, dxf_ext::model_center_to_dcs(v.view_center, v.view_twist()));
|
||||
w.p2(12, dxf_ext::model_center_to_dcs(v.view_center, twist));
|
||||
w.f(45, v.view_height);
|
||||
// View twist (degrees), when the viewport has one.
|
||||
if v.view_twist() != 0.0 {
|
||||
w.f(51, v.view_twist().to_degrees());
|
||||
if twist != 0.0 {
|
||||
w.f(51, twist.to_degrees());
|
||||
}
|
||||
// Status flags: 16384 = display locked, 32768 = always set, 65536 = clipped by the
|
||||
// 340 entity, 131072 = off.
|
||||
|
||||
@@ -95,7 +95,7 @@ pub(super) fn vport_table(w: &mut W, d: &Drawing, ext: Bounds2) {
|
||||
w.i(70, 0);
|
||||
w.p2(10, finite(t.min, Vec2::ZERO));
|
||||
w.p2(11, finite(t.max, Vec2::new(1.0, 1.0)));
|
||||
let twist = if t.twist.is_finite() { t.twist } else { 0.0 };
|
||||
let twist = cadcraft_geom::norm_angle(t.twist);
|
||||
w.p2(12, dxf_ext::model_center_to_dcs(finite(t.center, Vec2::ZERO), twist));
|
||||
// Snap grid origin and rotation (SNAPBASE, SNAPANG in degrees): R13+ files keep them here.
|
||||
w.p2(13, d.header.point("SNAPBASE").map(|p| p.xy()).filter(|p| p.is_finite()).unwrap_or(Vec2::ZERO));
|
||||
|
||||
@@ -136,7 +136,7 @@ fn write_tables(w: &mut W, plan: TableWritePlan<'_>) -> HashMap<String, String>
|
||||
w.s(2, &v.name);
|
||||
w.i(70, i64::from(v.layout.is_some()));
|
||||
w.f(40, v.height);
|
||||
let twist = if v.twist.is_finite() { v.twist } else { 0.0 };
|
||||
let twist = cadcraft_geom::norm_angle(v.twist);
|
||||
w.p2(10, dxf_ext::model_center_to_dcs(v.center, twist));
|
||||
w.f(41, v.width);
|
||||
w.p(11, Vec3::Z);
|
||||
|
||||
Reference in New Issue
Block a user