fix(insert): place block attributes by their ATTDEF geometry, follow the block (#255)
Inserting a block piled every attribute at the origin: each AttributeEntity was built from just tag + value with default geometry. Carry the full AttributeDefinition through the attreq flow and build attributes with AttributeEntity::from_definition, then apply the block's insertion transform so each lands in WCS at its proper position / alignment / rotation. Attributes are stored in world space, so moving the block must move them too. The MOVE command already did (acadrust translate_insert); apply_grip (grip-drag) and the Position X/Y/Z property edit now translate the attributes by the same world delta so they no longer stay behind. Rotate/scale/mirror of a block still don't carry the attributes — acadrust's transform_insert has no attribute pass — tracked separately. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
818638d3aa
commit
ab0a4f790c
4 changed files with 60 additions and 40 deletions
|
|
@ -79,9 +79,21 @@ fn apply_geom_prop(ins: &mut Insert, field: &str, value: &str) {
|
|||
return;
|
||||
};
|
||||
match field {
|
||||
"ins_x" => ins.insert_point.x = v,
|
||||
"ins_y" => ins.insert_point.y = v,
|
||||
"ins_z" => ins.insert_point.z = v,
|
||||
"ins_x" | "ins_y" | "ins_z" => {
|
||||
// Move the attributes by the same world delta as the insertion
|
||||
// point so they follow the block instead of staying put (#255).
|
||||
let ocs = Matrix3::arbitrary_axis(ins.normal);
|
||||
let old_world = ocs * ins.insert_point;
|
||||
match field {
|
||||
"ins_x" => ins.insert_point.x = v,
|
||||
"ins_y" => ins.insert_point.y = v,
|
||||
_ => ins.insert_point.z = v,
|
||||
}
|
||||
let delta = ocs * ins.insert_point - old_world;
|
||||
for att in &mut ins.attributes {
|
||||
acadrust::Entity::translate(att, delta);
|
||||
}
|
||||
}
|
||||
"x_scale" => ins.set_x_scale(v),
|
||||
"y_scale" => ins.set_y_scale(v),
|
||||
"z_scale" => ins.set_z_scale(v),
|
||||
|
|
@ -96,13 +108,18 @@ fn apply_grip(ins: &mut Insert, _grip_id: usize, apply: GripApply) {
|
|||
// whose extrusion direction isn't +Z moves along world axes. Identity OCS
|
||||
// for a +Z normal, so this matches the old direct assignment there.
|
||||
let ocs = Matrix3::arbitrary_axis(ins.normal);
|
||||
let old_world = ocs * ins.insert_point;
|
||||
let world = match apply {
|
||||
GripApply::Absolute(p) => Vector3::new(p.x as f64, p.y as f64, p.z as f64),
|
||||
GripApply::Translate(d) => {
|
||||
ocs * ins.insert_point + Vector3::new(d.x as f64, d.y as f64, d.z as f64)
|
||||
}
|
||||
GripApply::Translate(d) => old_world + Vector3::new(d.x as f64, d.y as f64, d.z as f64),
|
||||
};
|
||||
ins.insert_point = ocs.transpose() * world;
|
||||
// Attributes sit in world space beside the block, so move them by the same
|
||||
// world delta — otherwise a grip-drag leaves the attribute text behind (#255).
|
||||
let delta = world - old_world;
|
||||
for att in &mut ins.attributes {
|
||||
acadrust::Entity::translate(att, delta);
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_transform(ins: &mut Insert, t: &EntityTransform) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue