From df7f81a07dd09891c79adb9b83abf6368129c42e Mon Sep 17 00:00:00 2001 From: ramox81 <184937705+ramox81@users.noreply.github.com> Date: Wed, 14 Oct 2026 12:57:42 +0300 Subject: [PATCH] REFEDIT: nested pick messages and the session note Picking nested objects reports what each pick added ("1 entity added", "0 entities added" for an object already in the set), a pick on empty space starts a window ("Specify opposite corner:"; a window dragged to the right takes the objects inside it, to the left those it touches), and a typed point picks the object it lies on. From the Reference Edit dialog the item count is printed when the session opens, followed by "Use REFCLOSE or the Refedit toolbar to end reference editing session." Co-Authored-By: Claude Opus 5.5 --- locales/ar-SA/opencadstudio.ftl | 3 + locales/bg-BG/opencadstudio.ftl | 3 + locales/cs-CZ/opencadstudio.ftl | 3 + locales/de-DE/opencadstudio.ftl | 3 + locales/el-GR/opencadstudio.ftl | 3 + locales/en-US/opencadstudio.ftl | 3 + locales/es-ES/opencadstudio.ftl | 3 + locales/fi-FI/opencadstudio.ftl | 3 + locales/fr-FR/opencadstudio.ftl | 3 + locales/hi-IN/opencadstudio.ftl | 3 + locales/hu-HU/opencadstudio.ftl | 3 + locales/it-IT/opencadstudio.ftl | 3 + locales/ja-JP/opencadstudio.ftl | 3 + locales/ko-KR/opencadstudio.ftl | 3 + locales/lo-LA/opencadstudio.ftl | 3 + locales/nl-NL/opencadstudio.ftl | 3 + locales/pl-PL/opencadstudio.ftl | 3 + locales/pt-BR/opencadstudio.ftl | 3 + locales/ru-RU/opencadstudio.ftl | 3 + locales/tr-TR/opencadstudio.ftl | 3 + locales/zh-CN/opencadstudio.ftl | 3 + locales/zh-TW/opencadstudio.ftl | 3 + src/app/commands/refedit.rs | 17 +++- src/locale_catalog.rs | 3 + src/modules/draw/modify/refedit.rs | 120 ++++++++++++++++++++++++++--- 25 files changed, 195 insertions(+), 11 deletions(-) diff --git a/locales/ar-SA/opencadstudio.ftl b/locales/ar-SA/opencadstudio.ftl index 58d54f9a0..a30573a1c 100644 --- a/locales/ar-SA/opencadstudio.ftl +++ b/locales/ar-SA/opencadstudio.ftl @@ -6485,6 +6485,9 @@ view-background = .select-image = Select Background Image ref-edit = + .entities-added = __ocs_fmt_0__ entities added + .use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session. + .opposite-corner = Specify opposite corner: .add-to-working-set = إضافة إلى مجموعة العمل .remove-from-working-set = إزالة من مجموعة العمل .toolbar-objects = كائنات diff --git a/locales/bg-BG/opencadstudio.ftl b/locales/bg-BG/opencadstudio.ftl index acb1ac860..4d36dc851 100644 --- a/locales/bg-BG/opencadstudio.ftl +++ b/locales/bg-BG/opencadstudio.ftl @@ -6473,6 +6473,9 @@ view-background = .select-image = Select Background Image ref-edit = + .entities-added = __ocs_fmt_0__ entities added + .use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session. + .opposite-corner = Specify opposite corner: .add-to-working-set = Добави към работния набор .remove-from-working-set = Премахни от работния набор .toolbar-objects = обекта diff --git a/locales/cs-CZ/opencadstudio.ftl b/locales/cs-CZ/opencadstudio.ftl index c6f6151c8..e36c18500 100644 --- a/locales/cs-CZ/opencadstudio.ftl +++ b/locales/cs-CZ/opencadstudio.ftl @@ -6470,6 +6470,9 @@ view-background = .select-image = Select Background Image ref-edit = + .entities-added = __ocs_fmt_0__ entities added + .use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session. + .opposite-corner = Specify opposite corner: .add-to-working-set = Přidat do pracovní sady .remove-from-working-set = Odebrat z pracovní sady .toolbar-objects = objektů diff --git a/locales/de-DE/opencadstudio.ftl b/locales/de-DE/opencadstudio.ftl index 9686e0aaf..2e19397ff 100644 --- a/locales/de-DE/opencadstudio.ftl +++ b/locales/de-DE/opencadstudio.ftl @@ -6471,6 +6471,9 @@ view-background = .select-image = Select Background Image ref-edit = + .entities-added = __ocs_fmt_0__ entities added + .use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session. + .opposite-corner = Specify opposite corner: .add-to-working-set = Zum Arbeitssatz hinzufügen .remove-from-working-set = Aus dem Arbeitssatz entfernen .toolbar-objects = Objekte diff --git a/locales/el-GR/opencadstudio.ftl b/locales/el-GR/opencadstudio.ftl index 26eca339a..1947fcb4a 100644 --- a/locales/el-GR/opencadstudio.ftl +++ b/locales/el-GR/opencadstudio.ftl @@ -6473,6 +6473,9 @@ view-background = .select-image = Select Background Image ref-edit = + .entities-added = __ocs_fmt_0__ entities added + .use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session. + .opposite-corner = Specify opposite corner: .add-to-working-set = Προσθήκη στο σύνολο εργασίας .remove-from-working-set = Αφαίρεση από το σύνολο εργασίας .toolbar-objects = αντικείμενα diff --git a/locales/en-US/opencadstudio.ftl b/locales/en-US/opencadstudio.ftl index 0f4734280..7afea647c 100644 --- a/locales/en-US/opencadstudio.ftl +++ b/locales/en-US/opencadstudio.ftl @@ -6472,6 +6472,9 @@ view-background = .select-image = Select Background Image ref-edit = + .entities-added = __ocs_fmt_0__ entities added + .use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session. + .opposite-corner = Specify opposite corner: .add-to-working-set = Add to Working Set .remove-from-working-set = Remove from Working Set .toolbar-objects = objects diff --git a/locales/es-ES/opencadstudio.ftl b/locales/es-ES/opencadstudio.ftl index 4ae2ed045..9369dbb40 100644 --- a/locales/es-ES/opencadstudio.ftl +++ b/locales/es-ES/opencadstudio.ftl @@ -6473,6 +6473,9 @@ view-background = .select-image = Select Background Image ref-edit = + .entities-added = __ocs_fmt_0__ entities added + .use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session. + .opposite-corner = Specify opposite corner: .add-to-working-set = Añadir al conjunto de trabajo .remove-from-working-set = Eliminar del conjunto de trabajo .toolbar-objects = objetos diff --git a/locales/fi-FI/opencadstudio.ftl b/locales/fi-FI/opencadstudio.ftl index 950164de4..f3201449c 100644 --- a/locales/fi-FI/opencadstudio.ftl +++ b/locales/fi-FI/opencadstudio.ftl @@ -6470,6 +6470,9 @@ view-background = .select-image = Select Background Image ref-edit = + .entities-added = __ocs_fmt_0__ entities added + .use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session. + .opposite-corner = Specify opposite corner: .add-to-working-set = Lisää työjoukkoon .remove-from-working-set = Poista työjoukosta .toolbar-objects = objektia diff --git a/locales/fr-FR/opencadstudio.ftl b/locales/fr-FR/opencadstudio.ftl index 8b24070bd..c2645e706 100644 --- a/locales/fr-FR/opencadstudio.ftl +++ b/locales/fr-FR/opencadstudio.ftl @@ -6473,6 +6473,9 @@ view-background = .select-image = Select Background Image ref-edit = + .entities-added = __ocs_fmt_0__ entities added + .use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session. + .opposite-corner = Specify opposite corner: .add-to-working-set = Ajouter au jeu de travail .remove-from-working-set = Supprimer du jeu de travail .toolbar-objects = objets diff --git a/locales/hi-IN/opencadstudio.ftl b/locales/hi-IN/opencadstudio.ftl index 0aab05d14..8fcf188f5 100644 --- a/locales/hi-IN/opencadstudio.ftl +++ b/locales/hi-IN/opencadstudio.ftl @@ -6461,6 +6461,9 @@ view-background = .select-image = Select Background Image ref-edit = + .entities-added = __ocs_fmt_0__ entities added + .use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session. + .opposite-corner = Specify opposite corner: .add-to-working-set = कार्य सेट में जोड़ें .remove-from-working-set = कार्य सेट से हटाएँ .toolbar-objects = ऑब्जेक्ट diff --git a/locales/hu-HU/opencadstudio.ftl b/locales/hu-HU/opencadstudio.ftl index 4565836cd..6af9ce6cf 100644 --- a/locales/hu-HU/opencadstudio.ftl +++ b/locales/hu-HU/opencadstudio.ftl @@ -6457,6 +6457,9 @@ view-background = .select-image = Select Background Image ref-edit = + .entities-added = __ocs_fmt_0__ entities added + .use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session. + .opposite-corner = Specify opposite corner: .add-to-working-set = Hozzáadás a munkakészlethez .remove-from-working-set = Eltávolítás a munkakészletből .toolbar-objects = objektum diff --git a/locales/it-IT/opencadstudio.ftl b/locales/it-IT/opencadstudio.ftl index 9f8ace95c..24d2da5ad 100644 --- a/locales/it-IT/opencadstudio.ftl +++ b/locales/it-IT/opencadstudio.ftl @@ -6472,6 +6472,9 @@ view-background = .select-image = Select Background Image ref-edit = + .entities-added = __ocs_fmt_0__ entities added + .use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session. + .opposite-corner = Specify opposite corner: .add-to-working-set = Aggiungi al gruppo di lavoro .remove-from-working-set = Rimuovi dal gruppo di lavoro .toolbar-objects = oggetti diff --git a/locales/ja-JP/opencadstudio.ftl b/locales/ja-JP/opencadstudio.ftl index 6703c8b44..af3c245a5 100644 --- a/locales/ja-JP/opencadstudio.ftl +++ b/locales/ja-JP/opencadstudio.ftl @@ -6461,6 +6461,9 @@ view-background = .select-image = Select Background Image ref-edit = + .entities-added = __ocs_fmt_0__ entities added + .use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session. + .opposite-corner = Specify opposite corner: .add-to-working-set = 作業セットに追加 .remove-from-working-set = 作業セットから除去 .toolbar-objects = 個のオブジェクト diff --git a/locales/ko-KR/opencadstudio.ftl b/locales/ko-KR/opencadstudio.ftl index b9bf8d88f..cb12d1b10 100644 --- a/locales/ko-KR/opencadstudio.ftl +++ b/locales/ko-KR/opencadstudio.ftl @@ -6472,6 +6472,9 @@ view-background = .select-image = Select Background Image ref-edit = + .entities-added = __ocs_fmt_0__ entities added + .use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session. + .opposite-corner = Specify opposite corner: .add-to-working-set = 작업 세트에 추가 .remove-from-working-set = 작업 세트에서 제거 .toolbar-objects = 개 객체 diff --git a/locales/lo-LA/opencadstudio.ftl b/locales/lo-LA/opencadstudio.ftl index 3fc078836..76691d11e 100644 --- a/locales/lo-LA/opencadstudio.ftl +++ b/locales/lo-LA/opencadstudio.ftl @@ -6473,6 +6473,9 @@ view-background = .select-image = Select Background Image ref-edit = + .entities-added = __ocs_fmt_0__ entities added + .use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session. + .opposite-corner = Specify opposite corner: .add-to-working-set = ເພີ່ມໃສ່ຊຸດເຮັດວຽກ .remove-from-working-set = ລຶບອອກຈາກຊຸດເຮັດວຽກ .toolbar-objects = ວັດຖຸ diff --git a/locales/nl-NL/opencadstudio.ftl b/locales/nl-NL/opencadstudio.ftl index 1aba8d7c3..e17fa57ec 100644 --- a/locales/nl-NL/opencadstudio.ftl +++ b/locales/nl-NL/opencadstudio.ftl @@ -6471,6 +6471,9 @@ view-background = .select-image = Select Background Image ref-edit = + .entities-added = __ocs_fmt_0__ entities added + .use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session. + .opposite-corner = Specify opposite corner: .add-to-working-set = Toevoegen aan werkset .remove-from-working-set = Verwijderen uit werkset .toolbar-objects = objecten diff --git a/locales/pl-PL/opencadstudio.ftl b/locales/pl-PL/opencadstudio.ftl index 0aa504dcc..e7a5a49ac 100644 --- a/locales/pl-PL/opencadstudio.ftl +++ b/locales/pl-PL/opencadstudio.ftl @@ -6472,6 +6472,9 @@ view-background = .select-image = Select Background Image ref-edit = + .entities-added = __ocs_fmt_0__ entities added + .use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session. + .opposite-corner = Specify opposite corner: .add-to-working-set = Dodaj do zbioru roboczego .remove-from-working-set = Usuń ze zbioru roboczego .toolbar-objects = obiekty diff --git a/locales/pt-BR/opencadstudio.ftl b/locales/pt-BR/opencadstudio.ftl index d68f4385d..15be3e15c 100644 --- a/locales/pt-BR/opencadstudio.ftl +++ b/locales/pt-BR/opencadstudio.ftl @@ -6473,6 +6473,9 @@ view-background = .select-image = Select Background Image ref-edit = + .entities-added = __ocs_fmt_0__ entities added + .use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session. + .opposite-corner = Specify opposite corner: .add-to-working-set = Adicionar ao conjunto de trabalho .remove-from-working-set = Remover do conjunto de trabalho .toolbar-objects = objetos diff --git a/locales/ru-RU/opencadstudio.ftl b/locales/ru-RU/opencadstudio.ftl index 25f2d76cc..de93cb86d 100644 --- a/locales/ru-RU/opencadstudio.ftl +++ b/locales/ru-RU/opencadstudio.ftl @@ -6474,6 +6474,9 @@ view-background = .select-image = Select Background Image ref-edit = + .entities-added = __ocs_fmt_0__ entities added + .use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session. + .opposite-corner = Specify opposite corner: .add-to-working-set = Добавить в рабочий набор .remove-from-working-set = Удалить из рабочего набора .toolbar-objects = объектов diff --git a/locales/tr-TR/opencadstudio.ftl b/locales/tr-TR/opencadstudio.ftl index da6152f3a..e493d5098 100644 --- a/locales/tr-TR/opencadstudio.ftl +++ b/locales/tr-TR/opencadstudio.ftl @@ -6394,6 +6394,9 @@ view-background = .select-image = Arka Plan Görüntüsü Seç ref-edit = + .entities-added = __ocs_fmt_0__ nesne eklendi + .use-refclose = Referans düzenleme oturumunu bitirmek için REFCLOSE komutunu veya referans düzenleme araç çubuğunu kullanın. + .opposite-corner = Karşı köşeyi belirtin: .add-to-working-set = Çalışma Kümesine Ekle .remove-from-working-set = Çalışma Kümesinden Çıkar .toolbar-objects = nesne diff --git a/locales/zh-CN/opencadstudio.ftl b/locales/zh-CN/opencadstudio.ftl index ea8690e95..fdefaae90 100644 --- a/locales/zh-CN/opencadstudio.ftl +++ b/locales/zh-CN/opencadstudio.ftl @@ -6456,6 +6456,9 @@ view-background = .select-image = Select Background Image ref-edit = + .entities-added = __ocs_fmt_0__ entities added + .use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session. + .opposite-corner = Specify opposite corner: .add-to-working-set = 添加到工作集 .remove-from-working-set = 从工作集删除 .toolbar-objects = 个对象 diff --git a/locales/zh-TW/opencadstudio.ftl b/locales/zh-TW/opencadstudio.ftl index aa43eb0bf..3f7e91475 100644 --- a/locales/zh-TW/opencadstudio.ftl +++ b/locales/zh-TW/opencadstudio.ftl @@ -6468,6 +6468,9 @@ view-background = .select-image = Select Background Image ref-edit = + .entities-added = __ocs_fmt_0__ entities added + .use-refclose = Use REFCLOSE or the Refedit toolbar to end reference editing session. + .opposite-corner = Specify opposite corner: .add-to-working-set = 加入工作集 .remove-from-working-set = 從工作集移除 .toolbar-objects = 個物件 diff --git a/src/app/commands/refedit.rs b/src/app/commands/refedit.rs index 3c924187b..351a825fe 100644 --- a/src/app/commands/refedit.rs +++ b/src/app/commands/refedit.rs @@ -256,7 +256,7 @@ impl OpenCADStudio { .map(|l| l.insert.value().to_string()) .collect(); return self.dispatch_command(&format!( - "REFEDIT_BEGIN:{}:{}:{}::{}:{}", + "REFEDIT_BEGIN:{}:{}:{}::{}:{}:1", state.top.value(), path.join(","), attributes as u8, @@ -293,6 +293,8 @@ impl OpenCADStudio { let unique = parts .next() .map_or(self.refedit_options.unique_names, |v| v == "1"); + // Opened from the Reference Edit dialog (REFEDIT, not -REFEDIT). + let from_dialog = parts.next() == Some("1"); if self.tabs[i].refedit_session.is_some() || self.reject_locked_edit(i, top) { return; } @@ -396,6 +398,19 @@ impl OpenCADStudio { self.tabs[i].scene.refedit_lock = lock; self.tabs[i].scene.deselect_all(); self.tabs[i].dirty = true; + if from_dialog { + match nested.len() { + 0 => {} + 1 => self.command_line.push_output(crate::t!("1 item selected").as_ref()), + n => self + .command_line + .push_output(crate::tf!("{} items selected", n).as_ref()), + } + self.command_line.push_output( + crate::t!("Use REFCLOSE or the Refedit toolbar to end reference editing session.") + .as_ref(), + ); + } // No active command — the definition's objects are edited freely // (move, grips, draw, erase…) until REFCLOSE. self.tabs[i].active_cmd = None; diff --git a/src/locale_catalog.rs b/src/locale_catalog.rs index 3d578321d..7c2808177 100644 --- a/src/locale_catalog.rs +++ b/src/locale_catalog.rs @@ -3,6 +3,9 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static str)> { match source { + "{} entities added" => Some(("ref-edit", "entities-added")), + "Use REFCLOSE or the Refedit toolbar to end reference editing session." => Some(("ref-edit", "use-refclose")), + "Specify opposite corner:" => Some(("ref-edit", "opposite-corner")), "Add to Working Set" => Some(("ref-edit", "add-to-working-set")), "Remove from Working Set" => Some(("ref-edit", "remove-from-working-set")), "Select reference:" => Some(("ref-edit", "select-reference")), diff --git a/src/modules/draw/modify/refedit.rs b/src/modules/draw/modify/refedit.rs index b1d25e969..918451570 100644 --- a/src/modules/draw/modify/refedit.rs +++ b/src/modules/draw/modify/refedit.rs @@ -414,6 +414,8 @@ pub struct RefEditOptionsCommand { /// Set when the Edit Reference dialog already chose the attribute /// option: the nested pick then opens the session directly. attributes: Option, + /// First corner of a window started by a pick on empty space. + corner: Option, } impl RefEditOptionsCommand { @@ -435,6 +437,7 @@ impl RefEditOptionsCommand { lock, unique, attributes: None, + corner: None, } } @@ -464,34 +467,81 @@ impl RefEditOptionsCommand { let nested: Vec = self.nested.iter().map(|h| h.value().to_string()).collect(); CmdResult::Relaunch( format!( - "REFEDIT_BEGIN:{}:{}:{}:{}:{}:{}", + "REFEDIT_BEGIN:{}:{}:{}:{}:{}:{}:{}", self.top.value(), path.join(","), attributes as u8, nested.join(","), self.lock as u8, - self.unique as u8 + self.unique as u8, + self.attributes.is_some() as u8 ), vec![], ) } - fn pick_nested(&mut self, point: DVec3) -> CmdResult { + /// A pick at `point`: the nearest object of the level within `tolerance` + /// (any distance when None), else the first corner of a window. + fn pick_nested(&mut self, point: DVec3, tolerance: Option) -> CmdResult { + if let Some(first) = self.corner.take() { + return self.window_nested(first, point); + } let nearest = self .hits .get(self.level) .into_iter() .flatten() .filter_map(|(h, paths)| paths_distance(paths, point).map(|d| (*h, d))) + .filter(|(_, d)| tolerance.is_none_or(|t| *d <= t)) .min_by(|a, b| a.1.total_cmp(&b.1)); match nearest { - Some((h, _)) if !self.nested.contains(&h) => { - self.nested.push(h); - CmdResult::ReportMeasurement(t!("1 entity added").into_owned()) + Some((h, _)) => { + let added = !self.nested.contains(&h); + if added { + self.nested.push(h); + } + CmdResult::ReportMeasurement(entities_added(added as usize)) + } + None => { + self.corner = Some(point); + CmdResult::NeedPoint } - _ => CmdResult::NeedPoint, } } + + /// The level's objects in the window from `first` to `second`: wholly + /// inside when it was dragged to the right, touching it when to the left. + fn window_nested(&mut self, first: DVec3, second: DVec3) -> CmdResult { + let (lo, hi) = (first.min(second), first.max(second)); + let crossing = second.x < first.x; + let inside = |p: &[f64; 3]| p[0] >= lo.x && p[0] <= hi.x && p[1] >= lo.y && p[1] <= hi.y; + let picked: Vec = self + .hits + .get(self.level) + .into_iter() + .flatten() + .filter(|(_, paths)| { + let points = || paths.iter().flatten(); + if crossing { + points().any(inside) + || paths.iter().any(|path| { + path.windows(2).any(|s| segment_meets_box(s[0], s[1], lo, hi)) + }) + } else { + points().next().is_some() && points().all(inside) + } + }) + .map(|(h, _)| *h) + .collect(); + let mut added = 0; + for h in picked { + if !self.nested.contains(&h) { + self.nested.push(h); + added += 1; + } + } + CmdResult::ReportMeasurement(entities_added(added)) + } } impl CadCommand for RefEditOptionsCommand { @@ -504,6 +554,9 @@ impl CadCommand for RefEditOptionsCommand { OptionStep::Method => { t!("Enter object selection method [All/Nested] :").into_owned() } + OptionStep::Nested if self.corner.is_some() => { + t!("Specify opposite corner:").into_owned() + } OptionStep::Nested => t!("Select nested objects:").into_owned(), OptionStep::Attributes => { t!("Display attribute definitions [Yes/No] :").into_owned() @@ -526,8 +579,13 @@ impl CadCommand for RefEditOptionsCommand { fn needs_entity_pick(&self) -> bool { matches!(self.step, OptionStep::Nested) } - fn on_entity_pick(&mut self, _handle: Handle, pt: DVec3) -> CmdResult { - self.pick_nested(pt) + fn on_entity_pick(&mut self, handle: Handle, pt: DVec3) -> CmdResult { + // A click on empty space starts a window, as does one beside the + // reference's objects. + if handle.is_null() { + return self.pick_nested(pt, Some(0.0)); + } + self.pick_nested(pt, None) } fn on_text_input(&mut self, text: &str) -> Option { let word = text.trim().to_ascii_uppercase(); @@ -554,7 +612,8 @@ impl CadCommand for RefEditOptionsCommand { } fn on_point(&mut self, pt: DVec3) -> CmdResult { match self.step { - OptionStep::Nested => self.pick_nested(pt), + // A typed point picks the object it lies on. + OptionStep::Nested => self.pick_nested(pt, Some(1e-6 * pt.length().max(1.0))), _ => CmdResult::NeedPoint, } } @@ -573,12 +632,14 @@ impl CadCommand for RefEditOptionsCommand { self.step = OptionStep::Attributes; CmdResult::NeedPoint } + OptionStep::Nested if self.corner.take().is_some() => CmdResult::NeedPoint, OptionStep::Nested => { let n = self.nested.len(); if n == 0 { return CmdResult::CancelWithMessage(t!("0 items selected").into_owned()); } if let Some(attributes) = self.attributes { + // The count and the session's note follow as it opens. return self.begin(attributes); } self.step = OptionStep::Attributes; @@ -593,6 +654,45 @@ impl CadCommand for RefEditOptionsCommand { } } +/// `N entity added` / `N entities added`. +fn entities_added(n: usize) -> String { + if n == 1 { + t!("1 entity added").into_owned() + } else { + crate::tf!("{} entities added", n).into_owned() + } +} + +/// Whether the segment from `a` to `b` crosses the box `lo`..`hi` (XY). +fn segment_meets_box(a: [f64; 3], b: [f64; 3], lo: DVec3, hi: DVec3) -> bool { + // Liang–Barsky clip of the segment against the box. + let (mut t0, mut t1) = (0.0f64, 1.0f64); + let d = [b[0] - a[0], b[1] - a[1]]; + for (p, q) in [ + (-d[0], a[0] - lo.x), + (d[0], hi.x - a[0]), + (-d[1], a[1] - lo.y), + (d[1], hi.y - a[1]), + ] { + if p == 0.0 { + if q < 0.0 { + return false; + } + } else { + let r = q / p; + if p < 0.0 { + t0 = t0.max(r); + } else { + t1 = t1.min(r); + } + if t0 > t1 { + return false; + } + } + } + true +} + // ── REFSET ──────────────────────────────────────────────────────────────── /// `Enter an option [Add/Remove] :` then `Select objects:`.