Commit graph cad-editor/src/entities/spline.rs
Author SHA1 Message Date
Hakan Seven
4b4fe5ca6d feat(grip): popup menus for polylines, spline, mline, hatch, leaders, text
Vocabulary added: AddFitPoint, RemoveFitPoint, Refit, RefineVertices,
TangentDirection, MoveWithText, StackText, UnstackText.

Polyline/Polyline2D/Polyline3D: vertex Add/Remove. MLine: same.
Spline: CV Add/Remove plus Refine Vertices (chord-midpoint insertion,
weights kept in sync, knots cleared so to_truck rebuilds uniform vec).
Hatch: centroid Origin/Angle/Scale (Angle and Scale prompt for value).
Leader: vertex Add/Remove (arrow + centroid stay Stretch-only).
MultiLeader: vertex Add/Remove Leader; MText location Move-with-Leader /
Move-Independent (menu live, structural edits stubbed). Text/MText:
Rotate prompts for degrees and sets rotation.

Spline, Leader, MultiLeader switched from impl_entity_basics! to manual
trait impls so grip_menu can be overridden.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 15:14:43 +03:00
Hakan Seven
9b5073752d refactor(entities): collapse trait wrapper boilerplate via macro
Every entity file ended with the same three-trait wrapper block:

    impl Grippable for T {
        fn grips(&self) -> Vec<GripDef> { grips(self) }
        fn apply_grip(&mut self, ...) { apply_grip(self, ...) }
    }
    impl PropertyEditable for T { ... }
    impl Transformable for T { ... }

— 23 lines of pure delegation around five same-named free functions.

Replace with `crate::impl_entity_basics!(T);` (a macro in
entities/traits.rs that expands to the three trait impls).

Applied where the file already follows the free-fn delegation
convention (Arc, Circle, Ellipse, Insert, Leader, Line, LwPolyline,
MultiLeader, Ole2Frame, Point, Spline, Viewport). Files that inlined
the trait method bodies directly (Ray, XLine, Shape, Solid, Tolerance,
MLine, Mesh, Solid3D/Region/Body, Table, RasterImage, Wipeout,
Underlay, Hatch, Polyline, Polyline2D, Polyline3D, Dimension) left
alone — they already skip the indirection. Text/MText/Attribute use
the with-text-style flavour and will move once that variant is needed
beyond the existing two manual impls.

A second macro `impl_entity_basics_with_text_styles!` is included for
the text-like flavour but no entity uses it yet.

Net: -204 lines.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 17:16:06 +03:00
Hakan Seven
288ccff95a fix(render): preserve f64 precision until world_offset subtraction
Entity converters were casting WCS coordinates to f32 before the renderer
subtracted world_offset, which destroyed sub-unit precision on drawings
sitting at large coordinates (typical UTM-style CAD files). The multileader
case made it visible — glyphs warped under rotation — but every entity
that emits TruckObject::Lines/SegmentedLines/key_vertices/fill_tris was
affected.

Type changes (in src/scene/acad_to_truck.rs):
- TruckObject::Lines / SegmentedLines: Vec<[f32; 3]> → Vec<[f64; 3]>
- TruckEntity::key_vertices / fill_tris: f32 → f64

All ~17 producer files updated to keep WCS coordinates in f64 right up to
the TruckEntity boundary. The consumer in scene/tessellate.rs now performs
`(x - ox) as f32` (f64 subtract, then cast) for points, key_vertices, and
fill_tris — preserving precision near the camera origin even when the
drawing sits at million-unit coordinates.

catmull_rom_pts (multileader spline) is now f64; the scene path widens its
offset-relative f32 ctrl points to f64 around the call and narrows back at
the output.

Notes:
- Table layout still uses glam::Vec3 (f32) internally; widened to f64 only
  at the TruckEntity boundary for type compatibility. Separate cleanup to
  switch its internal math to f64 is tracked.
- snap_pts and tangent_geoms remain f32 — they are UI feedback (snap
  candidates, tangent hints) and the precision is sufficient there.
2026-05-12 23:47:40 +03:00
Hakan
ca07268c7c cargo fmt 2026-05-12 10:36:15 +03:00
Hakan Seven
048bb41aef feat(render): solid fill for PolyfaceMesh and PolygonMesh entities
PolyfaceMesh and PolygonMesh were wireframe-only. They now render with
the same flat-color solid fill as Face3D entities.

- Add fill_tris: Vec<[f32;3]> to TruckEntity and WireModel
- PolyfaceMesh: fan-triangulate each face into fill_tris
- PolygonMesh: triangulate each grid quad into fill_tris
- tessellate.rs Lines branch: apply world_offset to fill_tris
- Face3DGpu::from_wires: collect fill_tris from all wires in addition
  to Face3D key_vertices quads
- upload_face3d: pass all_wires so fill_tris are batched into one draw call
2026-05-06 23:24:26 +03:00
Hakan Seven
7b7186a470 feat: use rational NURBS (NurbsCurve) when spline weights are present
Splines backed by rational NURBS (circles, conics) were tessellated as
uniform B-splines, losing the weighting that defines the curve shape.
Now BSplineCurve<Point3> is used only when weights are absent or empty;
when weight data is present a NurbsCurve<Vector4> is built from the
homogeneous control points so circles and conics render accurately.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 17:10:38 +03:00
Hakan Seven
0bb4209e2c fix: closed spline gap, hatch spline boundary, and spline commit grouping
- Spline: if flags.closed/periodic and B-spline endpoints don't meet,
  add an explicit closing Wire segment to eliminate the visual gap.
- Hatch BoundaryEdge::Spline: evaluate the B-spline at 16 uniform
  parameter samples (de Boor via truck BSplineCurve) instead of
  plotting raw control points as a polyline; falls back to control-
  point polyline for degenerate knot/degree inputs.
- Ellipse arc key_vertices and LWPolyline midpoint grips committed
  separately; this commit wraps the spline-related fixes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 02:26:26 +03:00
Hakan Seven
5216c247c2 fix: Spline snap points and TextStyle backward/upside-down rendering
Spline entities now expose fit_points (or control_points when no fit
points are defined) as key_vertices, enabling Endpoint and Midpoint
snap to reach spline construction points.

TextStyle is_backward flag is applied by negating the width_factor,
producing horizontally mirrored text. is_upside_down rotates the text
180°. Both tessellate_text_ex and text_local_bounds now handle negative
width_factor without clamping it to zero.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 22:10:32 +03:00
Hakan Seven
320312e81a fix: replace degenerate same-vertex edges with Point in lwpolyline and spline
Empty LwPolyline and single-control-point Spline fallbacks were calling
builder::line(&v, &v) with the same Rc vertex, triggering the
truck-topology panic "Two same vertices cannot construct an edge."

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 20:30:26 +03:00
Hakan Seven
d2fdac7f1e first commit 2026-03-22 14:56:27 +03:00