diff --git a/src/app/commands/blocks.rs b/src/app/commands/blocks.rs index e4e869ed0..d6b680840 100644 --- a/src/app/commands/blocks.rs +++ b/src/app/commands/blocks.rs @@ -371,7 +371,7 @@ impl OpenCADStudio { let wires = self.tabs[i].scene.wires_for_entities(&self.clipboard); use crate::modules::insert::insert_block::InsertBlockCommand; let cmd = - InsertBlockCommand::new_for_block(name, wires, base.as_vec3()); + InsertBlockCommand::new_for_block(name, wires, base); self.command_line.push_info(&cmd.prompt()); self.tabs[i].active_cmd = Some(Box::new(cmd)); } diff --git a/src/modules/insert/insert_block.rs b/src/modules/insert/insert_block.rs index b9e19c473..ed2225bd1 100644 --- a/src/modules/insert/insert_block.rs +++ b/src/modules/insert/insert_block.rs @@ -15,7 +15,7 @@ use crate::t; use codec::entities::{AttributeDefinition, AttributeEntity, Entity, Insert}; use codec::types::Vector3; use codec::EntityType; -use glam::{DVec3, Vec3}; +use glam::DVec3; use crate::app::settings::BlockInsertOptions; use crate::command::{CadCommand, CmdResult, DynField, InputKind, WorkingPlane}; @@ -130,6 +130,10 @@ pub struct InsertBlockCommand { /// through the same base-point convention the render path uses, so the /// host injects it when it resolves the block's ATTDEFs. block_base: Vector3, + /// Where the preview wires' block origin sits: zero for wires taken from + /// the definition, the clipboard base for paste-as-block, whose preview + /// is the clipboard in world coordinates. + preview_origin: DVec3, } impl InsertBlockCommand { @@ -157,6 +161,7 @@ impl InsertBlockCommand { pending_insert: None, plane: WorkingPlane::default(), block_base: Vector3::ZERO, + preview_origin: DVec3::ZERO, } } @@ -219,12 +224,13 @@ impl InsertBlockCommand { command } - /// Paste-as-block: the block is placed at the picked point. - pub fn new_for_block(name: String, preview_wires: Vec, base: Vec3) -> Self { + /// Paste-as-block: the block is placed at the picked point. The block + /// was defined around `base`, so its origin is the clipboard base. + pub fn new_for_block(name: String, preview_wires: Vec, base: DVec3) -> Self { let mut command = Self::base_state(Mode::Paste, Self::single_picker(&name)); command.name = name; command.preview = preview_wires; - command.base = base.as_dvec3(); + command.preview_origin = base; command.preset_scale = [Some(1.0); 3]; command.preset_rotation = Some(0.0); command.step = Step::Point; @@ -822,7 +828,7 @@ impl CadCommand for InsertBlockCommand { self.preset_scale[2].unwrap_or(1.0), ]; let (sin, cos) = self.preset_rotation.unwrap_or(0.0).sin_cos(); - let base = self.base; + let base = self.preview_origin + self.base; let origin = self.plane.to_local(pt); let plane = self.plane; self.preview