dxfscan 0.1.0

Binary DXF parser with typed entity data and lookup indices
Documentation
// SPDX-License-Identifier: ISC
use crate::point::Point3;
use crate::value::GroupValue;
use alloc::vec::Vec;

/// A WIPEOUT entity — an opaque polygonal mask.
///
/// The clip boundary is defined in normalized coordinates relative to the
/// image frame. To convert a clip vertex `(u, v)` to world coordinates:
///
/// ```text
/// world = insertion_point + u_vector * (u + 0.5) + v_vector * (v + 0.5)
/// ```
#[derive(Debug, Clone, Default)]
pub struct Wipeout {
    /// Frame insertion point.
    pub insertion_point: Point3,
    /// U-axis vector defining frame width and direction.
    pub u_vector: Point3,
    /// V-axis vector defining frame height and direction.
    pub v_vector: Point3,
    /// Clip boundary type.
    ///
    /// | Value | Meaning     |
    /// |------:|-------------|
    /// |     1 | Rectangular |
    /// |     2 | Polygonal   |
    pub clip_type: i16,
    /// Clip boundary vertices in normalized image-space coordinates.
    pub clip_vertices: Vec<(f64, f64)>,
    /// In-progress clip vertex being accumulated.
    current_u: Option<f64>,
}

impl Wipeout {
    pub(crate) fn feed(&mut self, code: u16, val: &GroupValue) {
        match code {
            71 => {
                if let Some(v) = val.as_i16() {
                    self.clip_type = v;
                }
            }
            14 => {
                if let Some(u) = val.as_f64() {
                    self.current_u = Some(u);
                }
            }
            24 => {
                if let Some(v) = val.as_f64() {
                    if let Some(u) = self.current_u.take() {
                        self.clip_vertices.push((u, v));
                    }
                }
            }
            _ => {
                if let Some(f) = val.as_f64() {
                    match code {
                        10 => self.insertion_point.x = f,
                        20 => self.insertion_point.y = f,
                        30 => self.insertion_point.z = f,
                        11 => self.u_vector.x = f,
                        21 => self.u_vector.y = f,
                        31 => self.u_vector.z = f,
                        12 => self.v_vector.x = f,
                        22 => self.v_vector.y = f,
                        32 => self.v_vector.z = f,
                        _ => {}
                    }
                }
            }
        }
    }
}