- Add transform_ellipse_geometry helper in scene::view::transform to compute exact principal semi-axes, normal, ratio, and shifted arc parameters under any affine transform (negative scales, reflections, negative rotations, non-uniform scaling, and translations).
- Use transform_ellipse_geometry in block_cache::transform_tangent for TangentGeom::PlanarEllipse so GPU analytical instances and curve endpoints match true WCS positions.
- Update entities::ellipse::apply_transform to use transform_ellipse_geometry for complete scaling, rotation, mirroring, and affine transformations.
- Clean up tangent parameters in to_render for Ellipse so start_param and end_param are consistently unwrapped.
- Add comprehensive unit tests in transform.rs, block_cache.rs, and ellipse.rs verifying negative rotations, negative scales, and distant origins.
The codec and kernel repositories and crates are renamed opencadcodec and
opencadkernel. Inside OCS they are depended on under short keys, so code
reads `codec::`, `kernel::` and the new `graph::` (opencadgraph, the node
graph engine). File-format and protocol spellings stay as they were: the
ACIS product id `acadrust`, the ACADRUST_* switches and the plugin
version keys `acadrust_version` / `acadrust_source`.
A button left of MCP on the command line opens a translucent node graph
over the viewport, with a palette of object, input, math, logic, list,
text and geometry nodes added by click or drag. An object node owns
drawing entities and its rows are the Properties panel's own rows for
them: the single-object page is extracted from refresh_properties as
entity_property_sections, values use the control protocol's
property_json, and writes go through set_property_value with a property
target override, so the panel, MCP and the graph share one read/write
path. A list reaching an object row makes one entity per element. Each
graph action is one undo step; the canvas pans and zooms.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Follow-up to the LINE/POINT WCS fix - the same bug class elsewhere:
- 2D SOLID rendered its OCS corners raw in both the wire path and the
shared fill builder (solid_hatch_model); SHAPE placed its marker at
the raw OCS insertion. Both now map through the arbitrary axis.
- Grips: central wrap in view/dispatch.rs shows planar entities' grips
at their world position (OCS→WCS) and converts drags back (WCS→OCS
via the new wcs_point_to_ocs) - per-entity grip code stays in raw
field space, INSERT keeps handling its own OCS.
- Pulls acadrust 81ebfee: OCS-aware bounding boxes, translate,
transform and mirror for the ten planar entity types, so MOVE /
ROTATE / MIRROR and culling work on mirrored entities too.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Completes the f64 migration on the CPU data path: the only f32 left now
is the GPU/render/screen layer, which is architecturally required (wgpu
vertex buffers and iced are f32; f64 vertices would double memory).
- EntityTransform::Rotate.angle_rad and Scale.factor are now f64 (the
transform was already applied in f64 around the DVec3 center, so this
only preserves the typed angle/factor). apply_standard_transform and
apply_standard_scale take f64.
- CmdResult::ExtrudeEntity.height and AlignSelected.{angle_rad,scale}
are f64; the EXTRUDE height parses as f64.
- defaults.rs (last-used construction values: circle radius/diameter,
rotate angle, scale factor, offset/fillet/chamfer distance, array
spacing/counts/angle) moved from Cell<f32> to Cell<f64>. Array counts
round-trip through u32 (exact below 2^53).
- Consumers in circle/array/fillet/offset/rotate/scale/align/solid3d and
dimension.rs rotate_point/scale_point follow. `as f32` is kept only
where a value feeds a WireModel rubber-band/ghost (the preview path is
screen-space f32).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The OCS arbitrary-axis algorithm crossed the normal with Wx=(1,0,0) in the
else branch, which collapses to zero for an X-aligned normal (e.g.
N=(-1,0,0)): the OCS axes became zero and every point mapped to the
origin. The resulting coincident points fed a NaN truck arc whose
parameter_division never converged, hanging the load on "Parsing
entities". Cross with Wz=(0,0,1) per the DXF spec. (#142)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Move the 30 flat modules under src/scene/ into six folders by role:
convert (entity→geometry), text (fonts/shaping), model (render models),
pick (hit-test/selection/grips/xclip), view (camera/transform/render),
cache (block + property caches). pipeline/ is unchanged.
Full path migration — all `scene::X` references become
`scene::<group>::X`, no compatibility re-exports. render.rs items that
were `pub(super)` (parent was scene) become `pub(in crate::scene)` to
keep their original scene-wide visibility.
No behavior change; build and tests are green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>