feat: Shape entity support (render + grips + props + transform)
- src/entities/shape.rs: diamond marker at insertion point (SHX glyphs
cannot be rendered without the binary .shx file, so a placeholder is used)
- Grips: single insertion-point grip
- Properties: Name, Style (read-only), Insert X/Y/Z, Size, Rotation
- Transformable: translate, mirror, scale, rotate
- Registered in entities/mod.rs, entities/traits.rs, app/commands.rs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 23:30:27 +03:00
|
|
|
// SHAPE entity — reference to an .SHX shape-file glyph.
|
|
|
|
|
//
|
|
|
|
|
// Since .SHX binary files are not parsed, we render a small diamond marker
|
feat(entities): integrate remaining fields on text-based entities
AttributeDefinition / AttributeEntity were rendering as left-aligned
single-line text regardless of their stored alignment, generation flags,
or multiline settings. Bring both to parity with Text plus expose every
remaining field through the Properties panel:
- horizontal_alignment / vertical_alignment with bounds-based anchor
using alignment_point, mirroring Text's logic
- text_generation_flags bit 2 (backward) flips width_factor sign; bit 4
(upside-down) adds π to the rotation; combined with the TextStyle
flags via XOR (double-mirror cancels)
- multi-line splitting on \n / \P with line_count surfaced as info
- mtext_flag, is_multiline, line_count, lock_position, field_length,
AttributeFlags bits (invisible / constant / verify / preset /
annotative) surfaced as properties
- AttributeEntity.attdef_handle shown as the definition reference
- flags.constant marks the default-value field read-only
- flags.locked_position / lock_position blocks the position grip
Shape entity now applies rotation, relative_x_scale, and oblique_angle
to its placeholder diamond marker, and surfaces shape_number,
style_handle, thickness, and normal in the Properties panel.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 20:58:58 +03:00
|
|
|
// at the insertion point (same approach as unknown/unsupported entities)
|
|
|
|
|
// but apply the SHAPE's own rotation / oblique / width factor so the marker
|
|
|
|
|
// gives a rough indication of the glyph orientation.
|
feat: Shape entity support (render + grips + props + transform)
- src/entities/shape.rs: diamond marker at insertion point (SHX glyphs
cannot be rendered without the binary .shx file, so a placeholder is used)
- Grips: single insertion-point grip
- Properties: Name, Style (read-only), Insert X/Y/Z, Size, Rotation
- Transformable: translate, mirror, scale, rotate
- Registered in entities/mod.rs, entities/traits.rs, app/commands.rs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 23:30:27 +03:00
|
|
|
|
|
|
|
|
use acadrust::entities::Shape;
|
|
|
|
|
|
|
|
|
|
use crate::command::EntityTransform;
|
2026-05-12 10:36:15 +03:00
|
|
|
use crate::entities::common::{edit_prop as edit, ro_prop as ro, square_grip};
|
feat: Shape entity support (render + grips + props + transform)
- src/entities/shape.rs: diamond marker at insertion point (SHX glyphs
cannot be rendered without the binary .shx file, so a placeholder is used)
- Grips: single insertion-point grip
- Properties: Name, Style (read-only), Insert X/Y/Z, Size, Rotation
- Transformable: translate, mirror, scale, rotate
- Registered in entities/mod.rs, entities/traits.rs, app/commands.rs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 23:30:27 +03:00
|
|
|
use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible};
|
2026-06-16 11:33:46 +03:00
|
|
|
use crate::scene::convert::acad_to_truck::{TruckEntity, TruckObject};
|
|
|
|
|
use crate::scene::model::object::{GripApply, GripDef, PropSection};
|
|
|
|
|
use crate::scene::view::transform;
|
|
|
|
|
use crate::scene::model::wire_model::SnapHint;
|
feat: Shape entity support (render + grips + props + transform)
- src/entities/shape.rs: diamond marker at insertion point (SHX glyphs
cannot be rendered without the binary .shx file, so a placeholder is used)
- Grips: single insertion-point grip
- Properties: Name, Style (read-only), Insert X/Y/Z, Size, Rotation
- Transformable: translate, mirror, scale, rotate
- Registered in entities/mod.rs, entities/traits.rs, app/commands.rs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 23:30:27 +03:00
|
|
|
|
|
|
|
|
// ── Marker geometry ───────────────────────────────────────────────────────────
|
|
|
|
|
|
feat(entities): integrate remaining fields on text-based entities
AttributeDefinition / AttributeEntity were rendering as left-aligned
single-line text regardless of their stored alignment, generation flags,
or multiline settings. Bring both to parity with Text plus expose every
remaining field through the Properties panel:
- horizontal_alignment / vertical_alignment with bounds-based anchor
using alignment_point, mirroring Text's logic
- text_generation_flags bit 2 (backward) flips width_factor sign; bit 4
(upside-down) adds π to the rotation; combined with the TextStyle
flags via XOR (double-mirror cancels)
- multi-line splitting on \n / \P with line_count surfaced as info
- mtext_flag, is_multiline, line_count, lock_position, field_length,
AttributeFlags bits (invisible / constant / verify / preset /
annotative) surfaced as properties
- AttributeEntity.attdef_handle shown as the definition reference
- flags.constant marks the default-value field read-only
- flags.locked_position / lock_position blocks the position grip
Shape entity now applies rotation, relative_x_scale, and oblique_angle
to its placeholder diamond marker, and surfaces shape_number,
style_handle, thickness, and normal in the Properties panel.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 20:58:58 +03:00
|
|
|
/// Small diamond marker at the shape insertion point. The diamond is sized
|
|
|
|
|
/// by `size`, stretched horizontally by `relative_x_scale`, sheared by
|
|
|
|
|
/// `oblique_angle`, and rotated by `rotation`.
|
|
|
|
|
fn shape_marker(
|
|
|
|
|
ox: f64,
|
|
|
|
|
oy: f64,
|
|
|
|
|
oz: f64,
|
|
|
|
|
size: f64,
|
|
|
|
|
rotation: f64,
|
|
|
|
|
rel_x_scale: f64,
|
|
|
|
|
oblique_angle: f64,
|
|
|
|
|
) -> Vec<[f64; 3]> {
|
|
|
|
|
let s = size.abs().max(0.001) * 0.5;
|
2026-06-11 00:04:37 +03:00
|
|
|
let rx = s * if rel_x_scale.abs() < 1e-9 {
|
|
|
|
|
1.0
|
|
|
|
|
} else {
|
|
|
|
|
rel_x_scale
|
|
|
|
|
};
|
feat(entities): integrate remaining fields on text-based entities
AttributeDefinition / AttributeEntity were rendering as left-aligned
single-line text regardless of their stored alignment, generation flags,
or multiline settings. Bring both to parity with Text plus expose every
remaining field through the Properties panel:
- horizontal_alignment / vertical_alignment with bounds-based anchor
using alignment_point, mirroring Text's logic
- text_generation_flags bit 2 (backward) flips width_factor sign; bit 4
(upside-down) adds π to the rotation; combined with the TextStyle
flags via XOR (double-mirror cancels)
- multi-line splitting on \n / \P with line_count surfaced as info
- mtext_flag, is_multiline, line_count, lock_position, field_length,
AttributeFlags bits (invisible / constant / verify / preset /
annotative) surfaced as properties
- AttributeEntity.attdef_handle shown as the definition reference
- flags.constant marks the default-value field read-only
- flags.locked_position / lock_position blocks the position grip
Shape entity now applies rotation, relative_x_scale, and oblique_angle
to its placeholder diamond marker, and surfaces shape_number,
style_handle, thickness, and normal in the Properties panel.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 20:58:58 +03:00
|
|
|
let ry = s;
|
|
|
|
|
let local = [(0.0, ry), (rx, 0.0), (0.0, -ry), (-rx, 0.0)];
|
|
|
|
|
let (sin_r, cos_r) = (rotation.sin(), rotation.cos());
|
|
|
|
|
let ob = oblique_angle.tan();
|
|
|
|
|
let mut out: Vec<[f64; 3]> = Vec::with_capacity(6);
|
|
|
|
|
for &(x, y) in &local {
|
|
|
|
|
let sx = x + y * ob;
|
|
|
|
|
let lx = sx * cos_r - y * sin_r + ox;
|
|
|
|
|
let ly = sx * sin_r + y * cos_r + oy;
|
|
|
|
|
out.push([lx, ly, oz]);
|
|
|
|
|
}
|
|
|
|
|
// Close polygon + segment separator.
|
|
|
|
|
let first = out[0];
|
|
|
|
|
out.push(first);
|
|
|
|
|
out.push([f64::NAN; 3]);
|
|
|
|
|
out
|
feat: Shape entity support (render + grips + props + transform)
- src/entities/shape.rs: diamond marker at insertion point (SHX glyphs
cannot be rendered without the binary .shx file, so a placeholder is used)
- Grips: single insertion-point grip
- Properties: Name, Style (read-only), Insert X/Y/Z, Size, Rotation
- Transformable: translate, mirror, scale, rotate
- Registered in entities/mod.rs, entities/traits.rs, app/commands.rs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 23:30:27 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── TruckConvertible ──────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
impl TruckConvertible for Shape {
|
|
|
|
|
fn to_truck(&self, _document: &acadrust::CadDocument) -> Option<TruckEntity> {
|
2026-05-12 23:47:40 +03:00
|
|
|
let ox = self.insertion_point.x;
|
|
|
|
|
let oy = self.insertion_point.y;
|
|
|
|
|
let oz = self.insertion_point.z;
|
|
|
|
|
let size = self.size.abs().max(0.5);
|
feat: Shape entity support (render + grips + props + transform)
- src/entities/shape.rs: diamond marker at insertion point (SHX glyphs
cannot be rendered without the binary .shx file, so a placeholder is used)
- Grips: single insertion-point grip
- Properties: Name, Style (read-only), Insert X/Y/Z, Size, Rotation
- Transformable: translate, mirror, scale, rotate
- Registered in entities/mod.rs, entities/traits.rs, app/commands.rs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 23:30:27 +03:00
|
|
|
|
refactor(snap): producers emit f64 snap points (world_offset removal P3)
TruckEntity.snap_pts is now DVec3 and every entity producer builds snap
candidates straight from the acadrust f64 coordinates instead of casting
to f32 first (text, mtext, arc, circle, ellipse, point, shape, solid,
mline, mtext, attribute, tolerance, table, underlay, ole2frame, mesh,
multileader, dimension, block-cache). offset_snap_pts stays f64
throughout. Still offset-relative (inert) — but snap precision is no
longer capped at ~0.5 m by an early f32 cast, which fixes a latent
UTM-scale snap error and sets up the absolute-coordinate switch.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 22:10:29 +03:00
|
|
|
let snap_pt = glam::DVec3::new(ox, oy, oz);
|
feat(entities): integrate remaining fields on text-based entities
AttributeDefinition / AttributeEntity were rendering as left-aligned
single-line text regardless of their stored alignment, generation flags,
or multiline settings. Bring both to parity with Text plus expose every
remaining field through the Properties panel:
- horizontal_alignment / vertical_alignment with bounds-based anchor
using alignment_point, mirroring Text's logic
- text_generation_flags bit 2 (backward) flips width_factor sign; bit 4
(upside-down) adds π to the rotation; combined with the TextStyle
flags via XOR (double-mirror cancels)
- multi-line splitting on \n / \P with line_count surfaced as info
- mtext_flag, is_multiline, line_count, lock_position, field_length,
AttributeFlags bits (invisible / constant / verify / preset /
annotative) surfaced as properties
- AttributeEntity.attdef_handle shown as the definition reference
- flags.constant marks the default-value field read-only
- flags.locked_position / lock_position blocks the position grip
Shape entity now applies rotation, relative_x_scale, and oblique_angle
to its placeholder diamond marker, and surfaces shape_number,
style_handle, thickness, and normal in the Properties panel.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 20:58:58 +03:00
|
|
|
let pts = shape_marker(
|
|
|
|
|
ox,
|
|
|
|
|
oy,
|
|
|
|
|
oz,
|
|
|
|
|
size,
|
|
|
|
|
self.rotation,
|
|
|
|
|
self.relative_x_scale,
|
|
|
|
|
self.oblique_angle,
|
|
|
|
|
);
|
feat: Shape entity support (render + grips + props + transform)
- src/entities/shape.rs: diamond marker at insertion point (SHX glyphs
cannot be rendered without the binary .shx file, so a placeholder is used)
- Grips: single insertion-point grip
- Properties: Name, Style (read-only), Insert X/Y/Z, Size, Rotation
- Transformable: translate, mirror, scale, rotate
- Registered in entities/mod.rs, entities/traits.rs, app/commands.rs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 23:30:27 +03:00
|
|
|
|
|
|
|
|
Some(TruckEntity {
|
|
|
|
|
object: TruckObject::Lines(pts),
|
|
|
|
|
snap_pts: vec![(snap_pt, SnapHint::Insertion)],
|
|
|
|
|
tangent_geoms: vec![],
|
|
|
|
|
key_vertices: vec![[ox, oy, oz]],
|
2026-05-06 23:24:26 +03:00
|
|
|
fill_tris: vec![],
|
feat: Shape entity support (render + grips + props + transform)
- src/entities/shape.rs: diamond marker at insertion point (SHX glyphs
cannot be rendered without the binary .shx file, so a placeholder is used)
- Grips: single insertion-point grip
- Properties: Name, Style (read-only), Insert X/Y/Z, Size, Rotation
- Transformable: translate, mirror, scale, rotate
- Registered in entities/mod.rs, entities/traits.rs, app/commands.rs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 23:30:27 +03:00
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── Grippable ─────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
impl Grippable for Shape {
|
|
|
|
|
fn grips(&self) -> Vec<GripDef> {
|
|
|
|
|
vec![square_grip(
|
|
|
|
|
0,
|
2026-06-11 00:04:37 +03:00
|
|
|
glam::DVec3::new(
|
|
|
|
|
self.insertion_point.x,
|
|
|
|
|
self.insertion_point.y,
|
|
|
|
|
self.insertion_point.z,
|
feat: Shape entity support (render + grips + props + transform)
- src/entities/shape.rs: diamond marker at insertion point (SHX glyphs
cannot be rendered without the binary .shx file, so a placeholder is used)
- Grips: single insertion-point grip
- Properties: Name, Style (read-only), Insert X/Y/Z, Size, Rotation
- Transformable: translate, mirror, scale, rotate
- Registered in entities/mod.rs, entities/traits.rs, app/commands.rs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 23:30:27 +03:00
|
|
|
),
|
|
|
|
|
)]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn apply_grip(&mut self, grip_id: usize, apply: GripApply) {
|
|
|
|
|
if grip_id == 0 {
|
|
|
|
|
match apply {
|
|
|
|
|
GripApply::Translate(d) => {
|
|
|
|
|
self.insertion_point.x += d.x as f64;
|
|
|
|
|
self.insertion_point.y += d.y as f64;
|
|
|
|
|
self.insertion_point.z += d.z as f64;
|
|
|
|
|
}
|
|
|
|
|
GripApply::Absolute(p) => {
|
|
|
|
|
self.insertion_point.x = p.x as f64;
|
|
|
|
|
self.insertion_point.y = p.y as f64;
|
|
|
|
|
self.insertion_point.z = p.z as f64;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── PropertyEditable ──────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
impl PropertyEditable for Shape {
|
|
|
|
|
fn geometry_properties(&self, _text_style_names: &[String]) -> PropSection {
|
feat(entities): integrate remaining fields on text-based entities
AttributeDefinition / AttributeEntity were rendering as left-aligned
single-line text regardless of their stored alignment, generation flags,
or multiline settings. Bring both to parity with Text plus expose every
remaining field through the Properties panel:
- horizontal_alignment / vertical_alignment with bounds-based anchor
using alignment_point, mirroring Text's logic
- text_generation_flags bit 2 (backward) flips width_factor sign; bit 4
(upside-down) adds π to the rotation; combined with the TextStyle
flags via XOR (double-mirror cancels)
- multi-line splitting on \n / \P with line_count surfaced as info
- mtext_flag, is_multiline, line_count, lock_position, field_length,
AttributeFlags bits (invisible / constant / verify / preset /
annotative) surfaced as properties
- AttributeEntity.attdef_handle shown as the definition reference
- flags.constant marks the default-value field read-only
- flags.locked_position / lock_position blocks the position grip
Shape entity now applies rotation, relative_x_scale, and oblique_angle
to its placeholder diamond marker, and surfaces shape_number,
style_handle, thickness, and normal in the Properties panel.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 20:58:58 +03:00
|
|
|
let style_handle_display = match self.style_handle {
|
|
|
|
|
Some(h) if !h.is_null() => format!("{:X}", h.value()),
|
|
|
|
|
_ => "(none)".to_string(),
|
|
|
|
|
};
|
feat: Shape entity support (render + grips + props + transform)
- src/entities/shape.rs: diamond marker at insertion point (SHX glyphs
cannot be rendered without the binary .shx file, so a placeholder is used)
- Grips: single insertion-point grip
- Properties: Name, Style (read-only), Insert X/Y/Z, Size, Rotation
- Transformable: translate, mirror, scale, rotate
- Registered in entities/mod.rs, entities/traits.rs, app/commands.rs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 23:30:27 +03:00
|
|
|
PropSection {
|
|
|
|
|
title: "Geometry".into(),
|
|
|
|
|
props: vec![
|
2026-05-12 10:36:15 +03:00
|
|
|
ro("Name", "shp_name", self.shape_name.clone()),
|
feat(entities): integrate remaining fields on text-based entities
AttributeDefinition / AttributeEntity were rendering as left-aligned
single-line text regardless of their stored alignment, generation flags,
or multiline settings. Bring both to parity with Text plus expose every
remaining field through the Properties panel:
- horizontal_alignment / vertical_alignment with bounds-based anchor
using alignment_point, mirroring Text's logic
- text_generation_flags bit 2 (backward) flips width_factor sign; bit 4
(upside-down) adds π to the rotation; combined with the TextStyle
flags via XOR (double-mirror cancels)
- multi-line splitting on \n / \P with line_count surfaced as info
- mtext_flag, is_multiline, line_count, lock_position, field_length,
AttributeFlags bits (invisible / constant / verify / preset /
annotative) surfaced as properties
- AttributeEntity.attdef_handle shown as the definition reference
- flags.constant marks the default-value field read-only
- flags.locked_position / lock_position blocks the position grip
Shape entity now applies rotation, relative_x_scale, and oblique_angle
to its placeholder diamond marker, and surfaces shape_number,
style_handle, thickness, and normal in the Properties panel.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 20:58:58 +03:00
|
|
|
ro("Number", "shp_number", self.shape_number.to_string()),
|
2026-05-12 10:36:15 +03:00
|
|
|
ro("Style", "shp_style", self.style_name.clone()),
|
feat(entities): integrate remaining fields on text-based entities
AttributeDefinition / AttributeEntity were rendering as left-aligned
single-line text regardless of their stored alignment, generation flags,
or multiline settings. Bring both to parity with Text plus expose every
remaining field through the Properties panel:
- horizontal_alignment / vertical_alignment with bounds-based anchor
using alignment_point, mirroring Text's logic
- text_generation_flags bit 2 (backward) flips width_factor sign; bit 4
(upside-down) adds π to the rotation; combined with the TextStyle
flags via XOR (double-mirror cancels)
- multi-line splitting on \n / \P with line_count surfaced as info
- mtext_flag, is_multiline, line_count, lock_position, field_length,
AttributeFlags bits (invisible / constant / verify / preset /
annotative) surfaced as properties
- AttributeEntity.attdef_handle shown as the definition reference
- flags.constant marks the default-value field read-only
- flags.locked_position / lock_position blocks the position grip
Shape entity now applies rotation, relative_x_scale, and oblique_angle
to its placeholder diamond marker, and surfaces shape_number,
style_handle, thickness, and normal in the Properties panel.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 20:58:58 +03:00
|
|
|
ro("Style Handle", "shp_style_handle", style_handle_display),
|
2026-05-12 10:36:15 +03:00
|
|
|
edit("Insert X", "shp_ix", self.insertion_point.x),
|
|
|
|
|
edit("Insert Y", "shp_iy", self.insertion_point.y),
|
|
|
|
|
edit("Insert Z", "shp_iz", self.insertion_point.z),
|
|
|
|
|
edit("Size", "shp_sz", self.size),
|
|
|
|
|
edit("Rotation", "shp_rot", self.rotation.to_degrees()),
|
feat(entities): integrate remaining fields on text-based entities
AttributeDefinition / AttributeEntity were rendering as left-aligned
single-line text regardless of their stored alignment, generation flags,
or multiline settings. Bring both to parity with Text plus expose every
remaining field through the Properties panel:
- horizontal_alignment / vertical_alignment with bounds-based anchor
using alignment_point, mirroring Text's logic
- text_generation_flags bit 2 (backward) flips width_factor sign; bit 4
(upside-down) adds π to the rotation; combined with the TextStyle
flags via XOR (double-mirror cancels)
- multi-line splitting on \n / \P with line_count surfaced as info
- mtext_flag, is_multiline, line_count, lock_position, field_length,
AttributeFlags bits (invisible / constant / verify / preset /
annotative) surfaced as properties
- AttributeEntity.attdef_handle shown as the definition reference
- flags.constant marks the default-value field read-only
- flags.locked_position / lock_position blocks the position grip
Shape entity now applies rotation, relative_x_scale, and oblique_angle
to its placeholder diamond marker, and surfaces shape_number,
style_handle, thickness, and normal in the Properties panel.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 20:58:58 +03:00
|
|
|
edit("Width Factor", "shp_xs", self.relative_x_scale),
|
|
|
|
|
edit("Oblique Angle", "shp_ob", self.oblique_angle.to_degrees()),
|
|
|
|
|
edit("Thickness", "shp_th", self.thickness),
|
|
|
|
|
edit("Normal X", "shp_nx", self.normal.x),
|
|
|
|
|
edit("Normal Y", "shp_ny", self.normal.y),
|
|
|
|
|
edit("Normal Z", "shp_nz", self.normal.z),
|
feat: Shape entity support (render + grips + props + transform)
- src/entities/shape.rs: diamond marker at insertion point (SHX glyphs
cannot be rendered without the binary .shx file, so a placeholder is used)
- Grips: single insertion-point grip
- Properties: Name, Style (read-only), Insert X/Y/Z, Size, Rotation
- Transformable: translate, mirror, scale, rotate
- Registered in entities/mod.rs, entities/traits.rs, app/commands.rs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 23:30:27 +03:00
|
|
|
],
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn apply_geom_prop(&mut self, field: &str, value: &str) {
|
2026-05-12 10:36:15 +03:00
|
|
|
let Ok(v) = value.trim().parse::<f64>() else {
|
|
|
|
|
return;
|
|
|
|
|
};
|
feat: Shape entity support (render + grips + props + transform)
- src/entities/shape.rs: diamond marker at insertion point (SHX glyphs
cannot be rendered without the binary .shx file, so a placeholder is used)
- Grips: single insertion-point grip
- Properties: Name, Style (read-only), Insert X/Y/Z, Size, Rotation
- Transformable: translate, mirror, scale, rotate
- Registered in entities/mod.rs, entities/traits.rs, app/commands.rs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 23:30:27 +03:00
|
|
|
match field {
|
2026-05-12 10:36:15 +03:00
|
|
|
"shp_ix" => self.insertion_point.x = v,
|
|
|
|
|
"shp_iy" => self.insertion_point.y = v,
|
|
|
|
|
"shp_iz" => self.insertion_point.z = v,
|
|
|
|
|
"shp_sz" => self.size = v.max(0.001),
|
feat: Shape entity support (render + grips + props + transform)
- src/entities/shape.rs: diamond marker at insertion point (SHX glyphs
cannot be rendered without the binary .shx file, so a placeholder is used)
- Grips: single insertion-point grip
- Properties: Name, Style (read-only), Insert X/Y/Z, Size, Rotation
- Transformable: translate, mirror, scale, rotate
- Registered in entities/mod.rs, entities/traits.rs, app/commands.rs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 23:30:27 +03:00
|
|
|
"shp_rot" => self.rotation = v.to_radians(),
|
feat(entities): integrate remaining fields on text-based entities
AttributeDefinition / AttributeEntity were rendering as left-aligned
single-line text regardless of their stored alignment, generation flags,
or multiline settings. Bring both to parity with Text plus expose every
remaining field through the Properties panel:
- horizontal_alignment / vertical_alignment with bounds-based anchor
using alignment_point, mirroring Text's logic
- text_generation_flags bit 2 (backward) flips width_factor sign; bit 4
(upside-down) adds π to the rotation; combined with the TextStyle
flags via XOR (double-mirror cancels)
- multi-line splitting on \n / \P with line_count surfaced as info
- mtext_flag, is_multiline, line_count, lock_position, field_length,
AttributeFlags bits (invisible / constant / verify / preset /
annotative) surfaced as properties
- AttributeEntity.attdef_handle shown as the definition reference
- flags.constant marks the default-value field read-only
- flags.locked_position / lock_position blocks the position grip
Shape entity now applies rotation, relative_x_scale, and oblique_angle
to its placeholder diamond marker, and surfaces shape_number,
style_handle, thickness, and normal in the Properties panel.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 20:58:58 +03:00
|
|
|
"shp_xs" if v.abs() > 1e-9 => self.relative_x_scale = v,
|
|
|
|
|
"shp_ob" => self.oblique_angle = v.to_radians(),
|
|
|
|
|
"shp_th" => self.thickness = v,
|
|
|
|
|
"shp_nx" => self.normal.x = v,
|
|
|
|
|
"shp_ny" => self.normal.y = v,
|
|
|
|
|
"shp_nz" => self.normal.z = v,
|
feat: Shape entity support (render + grips + props + transform)
- src/entities/shape.rs: diamond marker at insertion point (SHX glyphs
cannot be rendered without the binary .shx file, so a placeholder is used)
- Grips: single insertion-point grip
- Properties: Name, Style (read-only), Insert X/Y/Z, Size, Rotation
- Transformable: translate, mirror, scale, rotate
- Registered in entities/mod.rs, entities/traits.rs, app/commands.rs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 23:30:27 +03:00
|
|
|
_ => {}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── Transformable ─────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
impl Transformable for Shape {
|
|
|
|
|
fn apply_transform(&mut self, t: &EntityTransform) {
|
|
|
|
|
transform::apply_standard_entity_transform(self, t, |entity, p1, p2| {
|
|
|
|
|
transform::reflect_xy_point(
|
|
|
|
|
&mut entity.insertion_point.x,
|
|
|
|
|
&mut entity.insertion_point.y,
|
|
|
|
|
p1,
|
|
|
|
|
p2,
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|