forked from 1b-agent/opencadstudio-upstream
Replace the line-based MTEXT pipeline with a run-aware parser + renderer.
Every DXF MTEXT inline code now reaches the stroke output: \H \W \Q \T \A
\C \c \f \F \M \X, the \p block (q/i/l/r/t/s), brace-scoped state, and
the \L\l \O\o \K\k decoration toggles.
Parser ([text_support]): emits Vec<MTextLine{ runs, align, indent_*,
tab_stops }> with per-run RunState; braces scope character state, paragraph
props persist across them.
Renderer ([mtext]): atomise → wrap → render. Per-run height/width/oblique/
tracking/font/colour/decorations/valign; paragraph indents and tab stops
honoured; default 4-em tab fallback.
Plumbing: tessellate() now returns Vec<WireModel>; TextStroke gains an
optional inline-colour override so per-run \C/\c emits one wire per colour.
cxf::tessellate_text_run adds a tracking multiplier. block_cache folds
multi-wire results into a single LocalWire (colour split preserved at
top-level, flattened inside cached defns).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
57 lines
2.1 KiB
Rust
57 lines
2.1 KiB
Rust
// acadrust -> truck topology conversion layer.
|
|
|
|
use acadrust::{CadDocument, EntityType};
|
|
use glam::Vec3;
|
|
use truck_modeling::{Edge, Solid, Vertex, Wire};
|
|
|
|
use crate::entities::traits::EntityTypeOps;
|
|
use crate::scene::wire_model::{SnapHint, TangentGeom};
|
|
|
|
/// One group of glyph strokes with its world-space origin stored in f64.
|
|
/// Strokes are in glyph-local space (origin = [0,0]) so that the large
|
|
/// world offset can be subtracted with f64 precision in tessellate.rs.
|
|
///
|
|
/// `color`, when set, overrides the entity colour for just this group — used
|
|
/// by MTEXT inline `\C` / `\c` per-run colour. Strokes sharing the same
|
|
/// (color, None) override are merged into one WireModel downstream; runs with
|
|
/// distinct colours emit their own WireModel.
|
|
pub struct TextStroke {
|
|
pub strokes: Vec<Vec<[f32; 2]>>,
|
|
pub origin: [f64; 2],
|
|
pub color: Option<[f32; 3]>,
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
pub enum TruckObject {
|
|
Point(Vertex),
|
|
Curve(Edge),
|
|
Contour(Wire),
|
|
Text(Vec<TextStroke>),
|
|
/// Pre-computed NaN-separated 3-D point list (leader lines, arrowheads, etc.).
|
|
/// Points are stored in WCS as **f64** so the large world_offset can be
|
|
/// subtracted in full precision in tessellate.rs before the f32 cast.
|
|
/// Casting WCS coordinates to f32 in the entity converters used to wreck
|
|
/// rotated sub-glyph precision on drawings far from origin.
|
|
Lines(Vec<[f64; 3]>),
|
|
/// Like Lines but linetype pattern restarts at each NaN-separated segment (plinegen=false).
|
|
SegmentedLines(Vec<[f64; 3]>),
|
|
Volume(Solid),
|
|
}
|
|
|
|
pub struct TruckEntity {
|
|
pub object: TruckObject,
|
|
pub snap_pts: Vec<(Vec3, SnapHint)>,
|
|
pub tangent_geoms: Vec<TangentGeom>,
|
|
/// Polyline vertex positions in WCS f64; converted to offset-relative f32
|
|
/// at the wire-model boundary.
|
|
pub key_vertices: Vec<[f64; 3]>,
|
|
/// Pre-triangulated fill geometry: flat list of WCS f64 vertices, 3 per
|
|
/// triangle. Non-empty for mesh-like entities (PolyfaceMesh, PolygonMesh)
|
|
/// that need solid fill.
|
|
pub fill_tris: Vec<[f64; 3]>,
|
|
}
|
|
|
|
pub fn convert(entity: &EntityType, document: &CadDocument) -> Option<TruckEntity> {
|
|
entity.to_truck_entity(document)
|
|
}
|