From d285fd781e44b35d937977a15aeddc39b67d4dad Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Thu, 15 Oct 2026 13:22:26 +0300 Subject: [PATCH] feat(measuregeom): Quick mode measures around the cursor MEASUREGEOM gains a Quick option. As the cursor moves, the nearest drawn geometry along the working plane's X and Y lines through it is measured live: cyan measurement lines and a Horizontal/Vertical readout by the cursor. A click prints the current readout and keeps measuring; Enter ends the command. The rays go through the scene's interaction index, so large drawings stay responsive. A structure-pick command whose miss message is empty now gets the click as a plain point instead of an error. Co-Authored-By: Claude Opus 5.5 --- locales/ar-SA/opencadstudio.ftl | 6 +- locales/bg-BG/opencadstudio.ftl | 6 +- locales/cs-CZ/opencadstudio.ftl | 6 +- locales/de-DE/opencadstudio.ftl | 6 +- locales/el-GR/opencadstudio.ftl | 6 +- locales/en-US/opencadstudio.ftl | 6 +- locales/es-ES/opencadstudio.ftl | 6 +- locales/fi-FI/opencadstudio.ftl | 6 +- locales/fr-FR/opencadstudio.ftl | 6 +- locales/hi-IN/opencadstudio.ftl | 6 +- locales/hu-HU/opencadstudio.ftl | 6 +- locales/it-IT/opencadstudio.ftl | 6 +- locales/ja-JP/opencadstudio.ftl | 6 +- locales/ko-KR/opencadstudio.ftl | 6 +- locales/lo-LA/opencadstudio.ftl | 6 +- locales/nl-NL/opencadstudio.ftl | 6 +- locales/pl-PL/opencadstudio.ftl | 6 +- locales/pt-BR/opencadstudio.ftl | 6 +- locales/ru-RU/opencadstudio.ftl | 6 +- locales/tr-TR/opencadstudio.ftl | 6 +- locales/zh-CN/opencadstudio.ftl | 6 +- locales/zh-TW/opencadstudio.ftl | 6 +- src/app/update/viewport.rs | 11 +- src/command.rs | 3 +- src/locale_catalog.rs | 2 +- src/modules/draw/inquiry/measuregeom.rs | 158 +++++++++++++++++++++++- src/scene/mod.rs | 14 +++ 27 files changed, 291 insertions(+), 29 deletions(-) diff --git a/locales/ar-SA/opencadstudio.ftl b/locales/ar-SA/opencadstudio.ftl index 8701aca70..1bdca29d6 100644 --- a/locales/ar-SA/opencadstudio.ftl +++ b/locales/ar-SA/opencadstudio.ftl @@ -2677,7 +2677,7 @@ inquiry = .principal-moments-about-centroid-i-4-j-4-k-4 = العزوم الرئيسية حول مركز الثقل I=__ocs_fmt_0__ J=__ocs_fmt_1__ K=__ocs_fmt_2__ .measure-select-object-to-measure = MEASURE حدد الكائن المراد قياسه: .measure-specify-segment-length = MEASURE حدد طول المقطع: - .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM أدخل خيارًا [مسافة/نصف قطر/زاوية/مساحة]: + .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM أدخل خيارًا [سريع/مسافة/نصف قطر/زاوية/مساحة]: .measuregeom-select-arc-or-circle = MEASUREGEOM حدد قوسًا أو دائرة: .measuregeom-specify-first-corner-point-enter-t = MEASUREGEOM حدد نقطة الزاوية الأولى (Enter للإلغاء): .measuregeom-specify-first-point = MEASUREGEOM حدد النقطة الأولى: @@ -6603,6 +6603,10 @@ measurement = .different-line = Select a different line. .invalid-point = Specify a point with finite coordinates. .degenerate-ray = The ray endpoint must differ from the angle vertex. + .quick = سريع + .quick-prompt = { $command } حرّك المؤشر فوق الأشكال؛ انقر للإبلاغ، Enter للخروج: + .quick-horizontal = أفقي = { $value } + .quick-vertical = عمودي = { $value } .area-preview = { $current } Preview total area = { $total } diff --git a/locales/bg-BG/opencadstudio.ftl b/locales/bg-BG/opencadstudio.ftl index 9021c3cb6..01d6458d0 100644 --- a/locales/bg-BG/opencadstudio.ftl +++ b/locales/bg-BG/opencadstudio.ftl @@ -2664,7 +2664,7 @@ inquiry = .principal-moments-about-centroid-i-4-j-4-k-4 = Главни моменти спрямо центъра на тежестта I=__ocs_fmt_0__ J=__ocs_fmt_1__ K=__ocs_fmt_2__ .measure-select-object-to-measure = MEASURE Избери обект за измерване: .measure-specify-segment-length = MEASURE Посочи дължина на сегмент: - .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Въведи опция [Разстояние/Радиус/Ъгъл/Площ]: + .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Въведи опция [Бързо/Разстояние/Радиус/Ъгъл/Площ]: .measuregeom-select-arc-or-circle = MEASUREGEOM Избери дъга или окръжност: .measuregeom-specify-first-corner-point-enter-t = MEASUREGEOM Посочи първа ъглова точка (Enter за отказ): .measuregeom-specify-first-point = MEASUREGEOM Посочи първа точка: @@ -6591,6 +6591,10 @@ measurement = .different-line = Select a different line. .invalid-point = Specify a point with finite coordinates. .degenerate-ray = The ray endpoint must differ from the angle vertex. + .quick = Бързо + .quick-prompt = { $command } Преместете курсора над геометрията; щракнете за отчет, Enter за изход: + .quick-horizontal = Хоризонтално = { $value } + .quick-vertical = Вертикално = { $value } .area-preview = { $current } Preview total area = { $total } diff --git a/locales/cs-CZ/opencadstudio.ftl b/locales/cs-CZ/opencadstudio.ftl index f0023b21a..641d25bde 100644 --- a/locales/cs-CZ/opencadstudio.ftl +++ b/locales/cs-CZ/opencadstudio.ftl @@ -2664,7 +2664,7 @@ inquiry = .principal-moments-about-centroid-i-4-j-4-k-4 = Hlavní momenty k těžišti I=__ocs_fmt_0__ J=__ocs_fmt_1__ K=__ocs_fmt_2__ .measure-select-object-to-measure = MEASURE Vyberte objekt k měření: .measure-specify-segment-length = MEASURE Zadejte délku segmentu: - .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Enter možnost [Vzdálenost/Poloměr/Úhel/Area]: + .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Enter možnost [Rychlé/Vzdálenost/Poloměr/Úhel/Area]: .measuregeom-select-arc-or-circle = MEASUREGEOM Vyberte oblouk nebo kružnici: .measuregeom-specify-first-corner-point-enter-t = MEASUREGEOM Určete první rohový bod (zrušení Enter): .measuregeom-specify-first-point = MEASUREGEOM Zadejte první bod: @@ -6588,6 +6588,10 @@ measurement = .different-line = Select a different line. .invalid-point = Specify a point with finite coordinates. .degenerate-ray = The ray endpoint must differ from the angle vertex. + .quick = Rychlé + .quick-prompt = { $command } Přesuňte kurzor nad geometrii; kliknutím vypíšete, Enter ukončí: + .quick-horizontal = Vodorovně = { $value } + .quick-vertical = Svisle = { $value } .area-preview = { $current } Preview total area = { $total } diff --git a/locales/de-DE/opencadstudio.ftl b/locales/de-DE/opencadstudio.ftl index 59f8b9705..fabe8978e 100644 --- a/locales/de-DE/opencadstudio.ftl +++ b/locales/de-DE/opencadstudio.ftl @@ -2665,7 +2665,7 @@ inquiry = .principal-moments-about-centroid-i-4-j-4-k-4 = Hauptträgheitsmomente um den Schwerpunkt I=__ocs_fmt_0__ J=__ocs_fmt_1__ K=__ocs_fmt_2__ .measure-select-object-to-measure = MEASURE Objekt auswählen, um zu messen: .measure-specify-segment-length = MEASURE Segmentlänge angeben: - .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Geben Sie eine Option ein [Distance/Radius/Angle/ARea]: + .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Geben Sie eine Option ein [Quick/Distance/Radius/Angle/ARea]: .measuregeom-select-arc-or-circle = MEASUREGEOM Bogen oder Kreis auswählen: .measuregeom-specify-first-corner-point-enter-t = MEASUREGEOM Ersten Eckpunkt angeben (Eingabe zum Abbrechen): .measuregeom-specify-first-point = MEASUREGEOM Geben Sie den ersten Punkt an: @@ -6589,6 +6589,10 @@ measurement = .different-line = Select a different line. .invalid-point = Specify a point with finite coordinates. .degenerate-ray = The ray endpoint must differ from the angle vertex. + .quick = Schnell + .quick-prompt = { $command } Cursor über die Geometrie bewegen; Klick zum Ausgeben, Eingabe zum Beenden: + .quick-horizontal = Horizontal = { $value } + .quick-vertical = Vertikal = { $value } .area-preview = { $current } Preview total area = { $total } diff --git a/locales/el-GR/opencadstudio.ftl b/locales/el-GR/opencadstudio.ftl index 60a8c6969..2909b23af 100644 --- a/locales/el-GR/opencadstudio.ftl +++ b/locales/el-GR/opencadstudio.ftl @@ -2664,7 +2664,7 @@ inquiry = .principal-moments-about-centroid-i-4-j-4-k-4 = Κύριες ροπές ως προς το κέντρο βάρους I=__ocs_fmt_0__ J=__ocs_fmt_1__ K=__ocs_fmt_2__ .measure-select-object-to-measure = MEASURE Επιλέξτε αντικείμενο προς μέτρηση: .measure-specify-segment-length = MEASURE Ορίστε μήκος τμήματος: - .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Δώστε επιλογή [Απόσταση/Ακτίνα/Γωνία/Εμβαδόν]: + .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Δώστε επιλογή [Γρήγορα/Απόσταση/Ακτίνα/Γωνία/Εμβαδόν]: .measuregeom-select-arc-or-circle = MEASUREGEOM Επιλέξτε τόξο ή κύκλο: .measuregeom-specify-first-corner-point-enter-t = MEASUREGEOM Ορίστε πρώτο σημείο γωνίας (Enter για ακύρωση): .measuregeom-specify-first-point = MEASUREGEOM Ορίστε πρώτο σημείο: @@ -6591,6 +6591,10 @@ measurement = .different-line = Select a different line. .invalid-point = Specify a point with finite coordinates. .degenerate-ray = The ray endpoint must differ from the angle vertex. + .quick = Γρήγορα + .quick-prompt = { $command } Μετακινήστε τον κέρσορα πάνω από τη γεωμετρία· κλικ για αναφορά, Enter για έξοδο: + .quick-horizontal = Οριζόντια = { $value } + .quick-vertical = Κατακόρυφα = { $value } .area-preview = { $current } Preview total area = { $total } diff --git a/locales/en-US/opencadstudio.ftl b/locales/en-US/opencadstudio.ftl index a2ffad1c1..152cc6375 100644 --- a/locales/en-US/opencadstudio.ftl +++ b/locales/en-US/opencadstudio.ftl @@ -2665,7 +2665,7 @@ inquiry = .principal-moments-about-centroid-i-4-j-4-k-4 = Principal moments about centroid I=__ocs_fmt_0__ J=__ocs_fmt_1__ K=__ocs_fmt_2__ .measure-select-object-to-measure = MEASURE Select object to measure: .measure-specify-segment-length = MEASURE Specify segment length: - .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Enter an option [Distance/Radius/Angle/ARea]: + .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Enter an option [Quick/Distance/Radius/Angle/ARea]: .measuregeom-select-arc-or-circle = MEASUREGEOM Select arc or circle: .measuregeom-specify-first-corner-point-enter-t = MEASUREGEOM Specify first corner point (Enter to cancel): .measuregeom-specify-first-point = MEASUREGEOM Specify first point: @@ -6590,6 +6590,10 @@ measurement = .different-line = Select a different line. .invalid-point = Specify a point with finite coordinates. .degenerate-ray = The ray endpoint must differ from the angle vertex. + .quick = Quick + .quick-prompt = { $command } Move the cursor over geometry; click to report, Enter to exit: + .quick-horizontal = Horizontal = { $value } + .quick-vertical = Vertical = { $value } .area-preview = { $current } Preview total area = { $total } diff --git a/locales/es-ES/opencadstudio.ftl b/locales/es-ES/opencadstudio.ftl index 919bc64cb..2104bc40c 100644 --- a/locales/es-ES/opencadstudio.ftl +++ b/locales/es-ES/opencadstudio.ftl @@ -2665,7 +2665,7 @@ inquiry = .principal-moments-about-centroid-i-4-j-4-k-4 = Momentos principales respecto al centroide I=__ocs_fmt_0__ J=__ocs_fmt_1__ K=__ocs_fmt_2__ .measure-select-object-to-measure = MEASURE Seleccione el objeto que desea medir: .measure-specify-segment-length = MEASURE Especifique la longitud del segmento: - .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Introduzca una opción [Distancia/Radio/Ángulo/Área]: + .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Introduzca una opción [Rápido/Distancia/Radio/Ángulo/Área]: .measuregeom-select-arc-or-circle = MEASUREGEOM Seleccione un arco o círculo: .measuregeom-specify-first-corner-point-enter-t = MEASUREGEOM Especifique el primer punto de esquina (Enter para cancelar): .measuregeom-specify-first-point = MEASUREGEOM Especifique el primer punto: @@ -6591,6 +6591,10 @@ measurement = .different-line = Select a different line. .invalid-point = Specify a point with finite coordinates. .degenerate-ray = The ray endpoint must differ from the angle vertex. + .quick = Rápido + .quick-prompt = { $command } Mueva el cursor sobre la geometría; haga clic para informar, Intro para salir: + .quick-horizontal = Horizontal = { $value } + .quick-vertical = Vertical = { $value } .area-preview = { $current } Preview total area = { $total } diff --git a/locales/fi-FI/opencadstudio.ftl b/locales/fi-FI/opencadstudio.ftl index fb3e1d5d1..dadf2e21e 100644 --- a/locales/fi-FI/opencadstudio.ftl +++ b/locales/fi-FI/opencadstudio.ftl @@ -2664,7 +2664,7 @@ inquiry = .principal-moments-about-centroid-i-4-j-4-k-4 = Päähitausmomentit painopisteen suhteen I=__ocs_fmt_0__ J=__ocs_fmt_1__ K=__ocs_fmt_2__ .measure-select-object-to-measure = MEASURE Valitse mitattava kohde: .measure-specify-segment-length = MEASURE Määritä segmentin pituus: - .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Enter vaihtoehto [etäisyys/säde/kulma/pinta-ala]: + .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Enter vaihtoehto [pika/etäisyys/säde/kulma/pinta-ala]: .measuregeom-select-arc-or-circle = MEASUREGEOM Valitse kaari tai ympyrä: .measuregeom-specify-first-corner-point-enter-t = MEASUREGEOM Määritä ensimmäinen kulmapiste (Enter peruuttaaksesi): .measuregeom-specify-first-point = MEASUREGEOM Määritä ensimmäinen piste: @@ -6588,6 +6588,10 @@ measurement = .different-line = Select a different line. .invalid-point = Specify a point with finite coordinates. .degenerate-ray = The ray endpoint must differ from the angle vertex. + .quick = Pika + .quick-prompt = { $command } Siirrä kohdistin geometrian päälle; napsauta raportoidaksesi, Enter lopettaa: + .quick-horizontal = Vaaka = { $value } + .quick-vertical = Pysty = { $value } .area-preview = { $current } Preview total area = { $total } diff --git a/locales/fr-FR/opencadstudio.ftl b/locales/fr-FR/opencadstudio.ftl index e9dcfdcde..2bb29a725 100644 --- a/locales/fr-FR/opencadstudio.ftl +++ b/locales/fr-FR/opencadstudio.ftl @@ -2665,7 +2665,7 @@ inquiry = .principal-moments-about-centroid-i-4-j-4-k-4 = Moments principaux au centre de gravité I=__ocs_fmt_0__ J=__ocs_fmt_1__ K=__ocs_fmt_2__ .measure-select-object-to-measure = MEASURE Sélectionnez l'objet à mesurer : .measure-specify-segment-length = MEASURE Spécifier la longueur du segment: - .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Saisissez une option [Distance/Radius/Angle/ARea] : + .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Saisissez une option [Quick/Distance/Radius/Angle/ARea] : .measuregeom-select-arc-or-circle = MEASUREGEOM Sélectionner l'arc ou le cercle: .measuregeom-specify-first-corner-point-enter-t = MEASUREGEOM Spécifiez le premier point de coin (Inscrivez pour annuler): .measuregeom-specify-first-point = MEASUREGEOM Préciser le premier point: @@ -6591,6 +6591,10 @@ measurement = .different-line = Select a different line. .invalid-point = Specify a point with finite coordinates. .degenerate-ray = The ray endpoint must differ from the angle vertex. + .quick = Rapide + .quick-prompt = { $command } Déplacez le curseur sur la géométrie ; cliquez pour afficher, Entrée pour quitter : + .quick-horizontal = Horizontale = { $value } + .quick-vertical = Verticale = { $value } .area-preview = { $current } Preview total area = { $total } diff --git a/locales/hi-IN/opencadstudio.ftl b/locales/hi-IN/opencadstudio.ftl index 45dfa6060..775ce9d2d 100644 --- a/locales/hi-IN/opencadstudio.ftl +++ b/locales/hi-IN/opencadstudio.ftl @@ -2653,7 +2653,7 @@ inquiry = .principal-moments-about-centroid-i-4-j-4-k-4 = केन्द्रक के सापेक्ष मुख्य आघूर्ण I=__ocs_fmt_0__ J=__ocs_fmt_1__ K=__ocs_fmt_2__ .measure-select-object-to-measure = MEASURE ऑब्जेक्ट को मापने के लिए चुनें: .measure-specify-segment-length = MEASURE सेगमेंट की लंबाई निर्दिष्ट करें: - .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM विकल्प दर्ज करें [दूरी / त्रिज्या / कोण / क्षेत्रफल]: + .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM विकल्प दर्ज करें [त्वरित / दूरी / त्रिज्या / कोण / क्षेत्रफल]: .measuregeom-select-arc-or-circle = MEASUREGEOM आर्क या सर्कल का चयन करें: .measuregeom-specify-first-corner-point-enter-t = MEASUREGEOM पहले कोने बिंदु निर्दिष्ट करें (निरस्त करने के लिए सक्षम): .measuregeom-specify-first-point = MEASUREGEOM पहली बिंदु निर्दिष्ट करें: @@ -6579,6 +6579,10 @@ measurement = .different-line = Select a different line. .invalid-point = Specify a point with finite coordinates. .degenerate-ray = The ray endpoint must differ from the angle vertex. + .quick = त्वरित + .quick-prompt = { $command } कर्सर को ज्यामिति पर ले जाएँ; रिपोर्ट के लिए क्लिक करें, बाहर निकलने के लिए Enter: + .quick-horizontal = क्षैतिज = { $value } + .quick-vertical = ऊर्ध्वाधर = { $value } .area-preview = { $current } Preview total area = { $total } diff --git a/locales/hu-HU/opencadstudio.ftl b/locales/hu-HU/opencadstudio.ftl index e61af14b8..dacea1c4c 100644 --- a/locales/hu-HU/opencadstudio.ftl +++ b/locales/hu-HU/opencadstudio.ftl @@ -2664,7 +2664,7 @@ inquiry = .principal-moments-about-centroid-i-4-j-4-k-4 = Fő tehetetlenségi nyomatékok a súlypontra I=__ocs_fmt_0__ J=__ocs_fmt_1__ K=__ocs_fmt_2__ .measure-select-object-to-measure = MEASURE Válassza ki a mérendő objektumot: .measure-specify-segment-length = MEASURE Adja meg a szegmens hosszát: - .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Válasszon beállítást [Distance/Radius/Angle/ARea]: + .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Válasszon beállítást [Quick/Distance/Radius/Angle/ARea]: .measuregeom-select-arc-or-circle = MEASUREGEOM Ív vagy kör kiválasztása: .measuregeom-specify-first-corner-point-enter-t = MEASUREGEOM Adja meg az első sarokpontot (Enter a megszakításhoz): .measuregeom-specify-first-point = MEASUREGEOM Adja meg az első pontot: @@ -6575,6 +6575,10 @@ measurement = .different-line = Jelöljön ki egy másik vonalat. .invalid-point = Adjon meg véges koordinátájú pontot. .degenerate-ray = A szár végpontja nem egyezhet meg a szög csúcspontjával. + .quick = Gyors + .quick-prompt = { $command } Vigye a kurzort a geometria fölé; kattintás: kiírás, Enter: kilépés: + .quick-horizontal = Vízszintes = { $value } + .quick-vertical = Függőleges = { $value } .area-preview = { $current } Előzetes összterület = { $total } diff --git a/locales/it-IT/opencadstudio.ftl b/locales/it-IT/opencadstudio.ftl index d20780e4b..ec7e22f51 100644 --- a/locales/it-IT/opencadstudio.ftl +++ b/locales/it-IT/opencadstudio.ftl @@ -2664,7 +2664,7 @@ inquiry = .principal-moments-about-centroid-i-4-j-4-k-4 = Momenti principali rispetto al baricentro I=__ocs_fmt_0__ J=__ocs_fmt_1__ K=__ocs_fmt_2__ .measure-select-object-to-measure = MEASURE Selezionare l'oggetto da misurare: .measure-specify-segment-length = MEASURE Specificare la lunghezza del segmento: - .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Enter un'opzione [Distanza/Raggio/Angolo/ARea]: + .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Enter un'opzione [Rapido/Distanza/Raggio/Angolo/ARea]: .measuregeom-select-arc-or-circle = MEASUREGEOM Selezionare arco o cerchio: .measuregeom-specify-first-corner-point-enter-t = MEASUREGEOM Specificare il primo punto d'angolo (Enter per annullare): .measuregeom-specify-first-point = MEASUREGEOM Specificare il primo punto: @@ -6590,6 +6590,10 @@ measurement = .different-line = Select a different line. .invalid-point = Specify a point with finite coordinates. .degenerate-ray = The ray endpoint must differ from the angle vertex. + .quick = Rapido + .quick-prompt = { $command } Spostare il cursore sulla geometria; clic per riportare, Invio per uscire: + .quick-horizontal = Orizzontale = { $value } + .quick-vertical = Verticale = { $value } .area-preview = { $current } Preview total area = { $total } diff --git a/locales/ja-JP/opencadstudio.ftl b/locales/ja-JP/opencadstudio.ftl index da6ef89fe..f11fc5204 100644 --- a/locales/ja-JP/opencadstudio.ftl +++ b/locales/ja-JP/opencadstudio.ftl @@ -2655,7 +2655,7 @@ inquiry = .principal-moments-about-centroid-i-4-j-4-k-4 = 重心まわりの主慣性モーメント I=__ocs_fmt_0__ J=__ocs_fmt_1__ K=__ocs_fmt_2__ .measure-select-object-to-measure = MEASURE 計測するオブジェクトを選択: .measure-specify-segment-length = MEASURE 区間長を指定: - .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM オプションを入力 [距離/半径/角度/面積]: + .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM オプションを入力 [クイック/距離/半径/角度/面積]: .measuregeom-select-arc-or-circle = MEASUREGEOM 円弧または円を選択: .measuregeom-specify-first-corner-point-enter-t = MEASUREGEOM 最初のコーナー点を指定(Enter でキャンセル): .measuregeom-specify-first-point = MEASUREGEOM 1 点目を指定: @@ -6579,6 +6579,10 @@ measurement = .different-line = Select a different line. .invalid-point = Specify a point with finite coordinates. .degenerate-ray = The ray endpoint must differ from the angle vertex. + .quick = クイック + .quick-prompt = { $command } カーソルを図形の上に移動; クリックで報告、Enter で終了: + .quick-horizontal = 水平 = { $value } + .quick-vertical = 垂直 = { $value } .area-preview = { $current } Preview total area = { $total } diff --git a/locales/ko-KR/opencadstudio.ftl b/locales/ko-KR/opencadstudio.ftl index e8fec7108..d010218d4 100644 --- a/locales/ko-KR/opencadstudio.ftl +++ b/locales/ko-KR/opencadstudio.ftl @@ -2664,7 +2664,7 @@ inquiry = .principal-moments-about-centroid-i-4-j-4-k-4 = 도심에 대한 주 모멘트 I=__ocs_fmt_0__ J=__ocs_fmt_1__ K=__ocs_fmt_2__ .measure-select-object-to-measure = MEASURE 측정할 물체 선택: .measure-specify-segment-length = MEASURE 세그먼트 길이 지정: - .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Enter 옵션 [거리/반경/각도/지역]: + .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Enter 옵션 [빠른/거리/반경/각도/지역]: .measuregeom-select-arc-or-circle = MEASUREGEOM 호 또는 원 선택: .measuregeom-specify-first-corner-point-enter-t = MEASUREGEOM 첫 번째 꼭지점 지정(취소하려면 Enter): .measuregeom-specify-first-point = MEASUREGEOM 첫 번째 점 지정: @@ -6590,6 +6590,10 @@ measurement = .different-line = Select a different line. .invalid-point = Specify a point with finite coordinates. .degenerate-ray = The ray endpoint must differ from the angle vertex. + .quick = 빠른 + .quick-prompt = { $command } 형상 위로 커서를 이동하십시오. 클릭하면 보고, Enter로 종료: + .quick-horizontal = 수평 = { $value } + .quick-vertical = 수직 = { $value } .area-preview = { $current } Preview total area = { $total } diff --git a/locales/lo-LA/opencadstudio.ftl b/locales/lo-LA/opencadstudio.ftl index 1fe49c396..0156752fd 100644 --- a/locales/lo-LA/opencadstudio.ftl +++ b/locales/lo-LA/opencadstudio.ftl @@ -2665,7 +2665,7 @@ inquiry = .principal-moments-about-centroid-i-4-j-4-k-4 = ໂມເມັນຫຼັກອ້ອມຈຸດສູນກາງມວນ I=__ocs_fmt_0__ J=__ocs_fmt_1__ K=__ocs_fmt_2__ .measure-select-object-to-measure = MEASURE ເລືອກວັດຖຸທີ່ຈະວັດແທກ: .measure-specify-segment-length = MEASURE ກຳນົດຄວາມຍາວຂອງສ່ວນແບ່ງ: - .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM ປ້ອນຕົວເລືອກ [Distance/Radius/Angle/ARea]: + .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM ປ້ອນຕົວເລືອກ [Quick/Distance/Radius/Angle/ARea]: .measuregeom-select-arc-or-circle = MEASUREGEOM ເລືອກສ່ວນໂຄ້ງ ຫຼື ວົງມົນ: .measuregeom-specify-first-corner-point-enter-t = MEASUREGEOM ກຳນົດຈຸດມຸມທຳອິດ (ກົດ Enter ເພື່ອຍົກເລີກ): .measuregeom-specify-first-point = MEASUREGEOM ກຳນົດຈຸດທຳອິດ: @@ -6591,6 +6591,10 @@ measurement = .different-line = Select a different line. .invalid-point = Specify a point with finite coordinates. .degenerate-ray = The ray endpoint must differ from the angle vertex. + .quick = ດ່ວນ + .quick-prompt = { $command } ເລື່ອນເຄີເຊີໄປເທິງຮູບຊົງ; ຄລິກເພື່ອລາຍງານ, Enter ເພື່ອອອກ: + .quick-horizontal = ແນວນອນ = { $value } + .quick-vertical = ແນວຕັ້ງ = { $value } .area-preview = { $current } Preview total area = { $total } diff --git a/locales/nl-NL/opencadstudio.ftl b/locales/nl-NL/opencadstudio.ftl index 6e34190f4..42c14ea0c 100644 --- a/locales/nl-NL/opencadstudio.ftl +++ b/locales/nl-NL/opencadstudio.ftl @@ -2665,7 +2665,7 @@ inquiry = .principal-moments-about-centroid-i-4-j-4-k-4 = Hoofdtraagheidsmomenten om het zwaartepunt I=__ocs_fmt_0__ J=__ocs_fmt_1__ K=__ocs_fmt_2__ .measure-select-object-to-measure = MEASURE Selecteer object om mee te meten: .measure-specify-segment-length = MEASURE segmentlengte specificeren: - .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Voer een optie in [Afstand / Straal / Hoek / Oppervlakte]: + .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Voer een optie in [Snel / Afstand / Straal / Hoek / Oppervlakte]: .measuregeom-select-arc-or-circle = MEASUREGEOM Selecteer boog of cirkel: .measuregeom-specify-first-corner-point-enter-t = MEASUREGEOM Geef het eerste hoekpunt op (Enter om te annuleren): .measuregeom-specify-first-point = MEASUREGEOM Geef het eerste punt op: @@ -6589,6 +6589,10 @@ measurement = .different-line = Select a different line. .invalid-point = Specify a point with finite coordinates. .degenerate-ray = The ray endpoint must differ from the angle vertex. + .quick = Snel + .quick-prompt = { $command } Beweeg de cursor over de geometrie; klik om te rapporteren, Enter om te stoppen: + .quick-horizontal = Horizontaal = { $value } + .quick-vertical = Verticaal = { $value } .area-preview = { $current } Preview total area = { $total } diff --git a/locales/pl-PL/opencadstudio.ftl b/locales/pl-PL/opencadstudio.ftl index 5afc7c700..35cfbf57f 100644 --- a/locales/pl-PL/opencadstudio.ftl +++ b/locales/pl-PL/opencadstudio.ftl @@ -2664,7 +2664,7 @@ inquiry = .principal-moments-about-centroid-i-4-j-4-k-4 = Główne momenty względem środka ciężkości I=__ocs_fmt_0__ J=__ocs_fmt_1__ K=__ocs_fmt_2__ .measure-select-object-to-measure = MEASURE Wybierz obiekt do pomiaru: .measure-specify-segment-length = MEASURE Określ długość segmentu: - .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Enter opcja [Odległość/Promień/Kąt/Powierzchnia]: + .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Enter opcja [Szybki/Odległość/Promień/Kąt/Powierzchnia]: .measuregeom-select-arc-or-circle = MEASUREGEOM Wybierz łuk lub okrąg: .measuregeom-specify-first-corner-point-enter-t = MEASUREGEOM Określ pierwszy punkt narożny (Enter, aby anulować): .measuregeom-specify-first-point = MEASUREGEOM Określ pierwszy punkt: @@ -6590,6 +6590,10 @@ measurement = .different-line = Select a different line. .invalid-point = Specify a point with finite coordinates. .degenerate-ray = The ray endpoint must differ from the angle vertex. + .quick = Szybki + .quick-prompt = { $command } Przesuń kursor nad geometrię; kliknij, aby podać wynik, Enter, aby zakończyć: + .quick-horizontal = Poziomo = { $value } + .quick-vertical = Pionowo = { $value } .area-preview = { $current } Preview total area = { $total } diff --git a/locales/pt-BR/opencadstudio.ftl b/locales/pt-BR/opencadstudio.ftl index ecbf12fe2..c49e81d75 100644 --- a/locales/pt-BR/opencadstudio.ftl +++ b/locales/pt-BR/opencadstudio.ftl @@ -2665,7 +2665,7 @@ inquiry = .principal-moments-about-centroid-i-4-j-4-k-4 = Momentos principais em relação ao centroide I=__ocs_fmt_0__ J=__ocs_fmt_1__ K=__ocs_fmt_2__ .measure-select-object-to-measure = MEASURE Selecione o objeto a medir: .measure-specify-segment-length = MEASURE Especifique o comprimento do segmento: - .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Insira uma opção [Distância/Raio/Ângulo/ÁRea]: + .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Insira uma opção [Rápido/Distância/Raio/Ângulo/ÁRea]: .measuregeom-select-arc-or-circle = MEASUREGEOM Selecione um arco ou círculo: .measuregeom-specify-first-corner-point-enter-t = MEASUREGEOM Especifique o primeiro ponto de canto (Enter para cancelar): .measuregeom-specify-first-point = MEASUREGEOM Especifique o primeiro ponto: @@ -6591,6 +6591,10 @@ measurement = .different-line = Select a different line. .invalid-point = Specify a point with finite coordinates. .degenerate-ray = The ray endpoint must differ from the angle vertex. + .quick = Rápido + .quick-prompt = { $command } Mova o cursor sobre a geometria; clique para informar, Enter para sair: + .quick-horizontal = Horizontal = { $value } + .quick-vertical = Vertical = { $value } .area-preview = { $current } Preview total area = { $total } diff --git a/locales/ru-RU/opencadstudio.ftl b/locales/ru-RU/opencadstudio.ftl index 0c48d9ed1..683169314 100644 --- a/locales/ru-RU/opencadstudio.ftl +++ b/locales/ru-RU/opencadstudio.ftl @@ -2668,7 +2668,7 @@ inquiry = .principal-moments-about-centroid-i-4-j-4-k-4 = Главные моменты относительно центра масс I=__ocs_fmt_0__ J=__ocs_fmt_1__ K=__ocs_fmt_2__ .measure-select-object-to-measure = MEASURE Выберите объект для измерения: .measure-specify-segment-length = MEASURE Укажите длину сегмента: - .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Введите опцию [Расстояние/Радиус/Англия/Арея]: + .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Введите опцию [Быстро/Расстояние/Радиус/Англия/Арея]: .measuregeom-select-arc-or-circle = MEASUREGEOM Выберите дугу или круг: .measuregeom-specify-first-corner-point-enter-t = MEASUREGEOM Укажите первую точку угла (введите для отмены): .measuregeom-specify-first-point = MEASUREGEOM Укажите первую точку: @@ -6592,6 +6592,10 @@ measurement = .different-line = Select a different line. .invalid-point = Specify a point with finite coordinates. .degenerate-ray = The ray endpoint must differ from the angle vertex. + .quick = Быстро + .quick-prompt = { $command } Наведите курсор на геометрию; щелчок — вывести, Enter — выход: + .quick-horizontal = По горизонтали = { $value } + .quick-vertical = По вертикали = { $value } .area-preview = { $current } Preview total area = { $total } diff --git a/locales/tr-TR/opencadstudio.ftl b/locales/tr-TR/opencadstudio.ftl index 62ce2a837..6cf148f60 100644 --- a/locales/tr-TR/opencadstudio.ftl +++ b/locales/tr-TR/opencadstudio.ftl @@ -2646,7 +2646,7 @@ inquiry = .principal-moments-about-centroid-i-4-j-4-k-4 = Ağırlık merkezine göre asal momentler I=__ocs_fmt_0__ J=__ocs_fmt_1__ K=__ocs_fmt_2__ .measure-select-object-to-measure = MEASURE Ölçülecek nesneyi seçin: .measure-specify-segment-length = MEASURE Parça uzunluğunu belirtin: - .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Bir seçenek girin [Mesafe/Yarıçap/Açı/Alan]: + .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM Bir seçenek girin [Hızlı/Mesafe/Yarıçap/Açı/Alan]: .measuregeom-select-arc-or-circle = MEASUREGEOM Yay veya çember seçin: .measuregeom-specify-first-corner-point-enter-t = MEASUREGEOM İlk köşe noktasını belirtin (iptal etmek için Enter): .measuregeom-specify-first-point = MEASUREGEOM İlk noktayı belirtin: @@ -6512,6 +6512,10 @@ measurement = .different-line = Select a different line. .invalid-point = Specify a point with finite coordinates. .degenerate-ray = The ray endpoint must differ from the angle vertex. + .quick = Hızlı + .quick-prompt = { $command } İmleci geometrinin üzerinde gezdirin; bildirmek için tıklayın, çıkmak için Enter: + .quick-horizontal = Yatay = { $value } + .quick-vertical = Dikey = { $value } .area-preview = { $current } Preview total area = { $total } diff --git a/locales/zh-CN/opencadstudio.ftl b/locales/zh-CN/opencadstudio.ftl index 0554f148a..384adc93c 100644 --- a/locales/zh-CN/opencadstudio.ftl +++ b/locales/zh-CN/opencadstudio.ftl @@ -2652,7 +2652,7 @@ inquiry = .principal-moments-about-centroid-i-4-j-4-k-4 = 关于质心的主力矩 I=__ocs_fmt_0__ J=__ocs_fmt_1__ K=__ocs_fmt_2__ .measure-select-object-to-measure = MEASURE 选择要定距等分的对象: .measure-specify-segment-length = MEASURE 指定线段长度: - .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM 输入选项 [距离/半径/角度/面积]: + .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM 输入选项 [快速/距离/半径/角度/面积]: .measuregeom-select-arc-or-circle = MEASUREGEOM 选择圆弧或圆: .measuregeom-specify-first-corner-point-enter-t = MEASUREGEOM 指定第一个角点(按 Enter 取消): .measuregeom-specify-first-point = MEASUREGEOM 指定第一点: @@ -6574,6 +6574,10 @@ measurement = .different-line = Select a different line. .invalid-point = Specify a point with finite coordinates. .degenerate-ray = The ray endpoint must differ from the angle vertex. + .quick = 快速 + .quick-prompt = { $command } 将光标移到几何图形上;单击报告,Enter 退出: + .quick-horizontal = 水平 = { $value } + .quick-vertical = 垂直 = { $value } .area-preview = { $current } Preview total area = { $total } diff --git a/locales/zh-TW/opencadstudio.ftl b/locales/zh-TW/opencadstudio.ftl index d8510b264..9afc4ece7 100644 --- a/locales/zh-TW/opencadstudio.ftl +++ b/locales/zh-TW/opencadstudio.ftl @@ -2664,7 +2664,7 @@ inquiry = .principal-moments-about-centroid-i-4-j-4-k-4 = 關於質心的主力矩 I=__ocs_fmt_0__ J=__ocs_fmt_1__ K=__ocs_fmt_2__ .measure-select-object-to-measure = MEASURE 選擇要定距等分的物件: .measure-specify-segment-length = MEASURE 指定線段長度: - .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM 輸入選項 [距離/半徑/角度/面積]: + .measuregeom-enter-an-option-distance-radius-an = MEASUREGEOM 輸入選項 [快速/距離/半徑/角度/面積]: .measuregeom-select-arc-or-circle = MEASUREGEOM 選擇圓弧或圓: .measuregeom-specify-first-corner-point-enter-t = MEASUREGEOM 指定第一個角點(按 Enter 取消): .measuregeom-specify-first-point = MEASUREGEOM 指定第一點: @@ -6586,6 +6586,10 @@ measurement = .different-line = Select a different line. .invalid-point = Specify a point with finite coordinates. .degenerate-ray = The ray endpoint must differ from the angle vertex. + .quick = 快速 + .quick-prompt = { $command } 將游標移到幾何圖形上;按一下回報,Enter 結束: + .quick-horizontal = 水平 = { $value } + .quick-vertical = 垂直 = { $value } .area-preview = { $current } Preview total area = { $total } diff --git a/src/app/update/viewport.rs b/src/app/update/viewport.rs index e343f07a3..3ae282e94 100644 --- a/src/app/update/viewport.rs +++ b/src/app/update/viewport.rs @@ -4656,8 +4656,15 @@ impl OpenCADStudio { .as_ref() .map(|c| c.object_pick_miss_message()) .unwrap_or("No object near click."); - self.command_line.push_error(msg); - None + if msg.is_empty() { + self.tabs[i] + .active_cmd + .as_mut() + .map(|c| c.on_point(pick_wcs)) + } else { + self.command_line.push_error(msg); + None + } } } else if self.tabs[i] .active_cmd diff --git a/src/command.rs b/src/command.rs index e62e98500..bca35fb77 100644 --- a/src/command.rs +++ b/src/command.rs @@ -2806,7 +2806,8 @@ pub trait CadCommand: Send { vec![] } - /// Message when `resolve_object_pick` returns none on click. + /// Message when `resolve_object_pick` returns none on click; an empty one + /// passes the click to `on_point` instead. fn object_pick_miss_message(&self) -> &'static str { "No object near click." } diff --git a/src/locale_catalog.rs b/src/locale_catalog.rs index 00ff2ac57..4cbc7e9ba 100644 --- a/src/locale_catalog.rs +++ b/src/locale_catalog.rs @@ -2069,7 +2069,7 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static "MEASURE Specify segment length:" => Some(("inquiry", "measure-specify-segment-length")), "MEASURE: entity type not supported or distance too large." => Some(("common", "measure-entity-type-not-supported-or-distance")), "MEASURE: {count} point(s) placed." => Some(("common", "measure-count-point-s-placed")), - "MEASUREGEOM Enter an option [Distance/Radius/Angle/ARea]:" => Some(("inquiry", "measuregeom-enter-an-option-distance-radius-an")), + "MEASUREGEOM Enter an option [Quick/Distance/Radius/Angle/ARea]:" => Some(("inquiry", "measuregeom-enter-an-option-distance-radius-an")), "MEASUREGEOM Select arc or circle:" => Some(("inquiry", "measuregeom-select-arc-or-circle")), "MEASUREGEOM Specify first corner point (Enter to cancel):" => Some(("inquiry", "measuregeom-specify-first-corner-point-enter-t")), "MEASUREGEOM Specify first point:" => Some(("inquiry", "measuregeom-specify-first-point")), diff --git a/src/modules/draw/inquiry/measuregeom.rs b/src/modules/draw/inquiry/measuregeom.rs index 890405056..e136f76d7 100644 --- a/src/modules/draw/inquiry/measuregeom.rs +++ b/src/modules/draw/inquiry/measuregeom.rs @@ -1,7 +1,7 @@ // MEASUREGEOM command (alias MEA) — multi-mode geometry measurement. // // First step prompts for a mode keyword: -// Distance / Radius / Angle / ARea +// Quick / Distance / Radius / Angle / ARea // then collects the geometry the mode needs and prints a one-line readout // via `CmdResult::Measurement`, ending the command. // @@ -10,6 +10,9 @@ // vertex, mirroring inquiry/area.rs for precision) + perimeter. // ANGLE — three points (vertex + two ray endpoints) → angle in degrees. // RADIUS — pick a Circle or Arc → radius + diameter. +// QUICK — no picks: as the cursor moves, the nearest geometry along the +// working plane's X and Y axes is measured live; a click +// reports the current readout and Enter ends the command. // // All arithmetic is kept in f64 (picked points stay full precision; downcasting // to f32 loses several hundredths of a unit at survey-scale coordinates). @@ -40,6 +43,7 @@ pub fn tool() -> ToolDef { enum Mode { /// Awaiting the mode keyword. Choose, + Quick, Distance, Area, Angle, @@ -65,6 +69,8 @@ pub struct MeasureGeomCommand { /// The picked entity for RADIUS, injected before `on_entity_pick`. picked: Option, plane: WorkingPlane, + /// QUICK readout for the last hovered cursor position. + quick: std::cell::RefCell>, } impl MeasureGeomCommand { @@ -77,6 +83,7 @@ impl MeasureGeomCommand { points: vec![], picked: None, plane: WorkingPlane::default(), + quick: std::cell::RefCell::new(None), } } @@ -255,6 +262,114 @@ impl MeasureGeomCommand { fn angle_msg(vertex: DVec3, a: DVec3, b: DVec3) -> Option { Self::angle_degrees(a - vertex, b - vertex).map(Self::angle_value_msg) } + + /// Signed offset along local `axis` (0 = X, 1 = Y) from `c` to where the + /// segment `a`–`b` crosses the line through `c` along that axis. + fn crossing(a: DVec3, b: DVec3, c: DVec3, axis: usize) -> Option { + let other = 1 - axis; + let (da, db) = (a[other] - c[other], b[other] - c[other]); + if da * db > 0.0 || da == db { + return None; + } + let t = da / (da - db); + Some(a[axis] + t * (b[axis] - a[axis]) - c[axis]) + } + + /// Nearest crossings of the drawn geometry with the working plane's X and + /// Y lines through `cursor`, as local offsets `[-X, +X, -Y, +Y]`. + fn quick_hits( + scene: &crate::scene::Scene, + plane: WorkingPlane, + cursor: DVec3, + ) -> [Option; 4] { + let c = plane.to_local(cursor); + // Long enough to leave the drawing from anywhere the cursor can be. + let reach = scene + .model_space_extents() + .map(|(lo, hi)| { + let (lo, hi) = (lo.as_dvec3(), hi.as_dvec3()); + (hi - lo).length() + (cursor - (lo + hi) * 0.5).length() + }) + .unwrap_or(0.0) + + 1.0; + let mut hits = [None; 4]; + for (axis, direction) in [plane.x, plane.y].into_iter().enumerate() { + let (a, b) = (cursor - direction * reach, cursor + direction * reach); + let pad = reach * 1e-9; + let candidates = scene.interaction_candidates_xy([ + a.x.min(b.x) - pad, + a.y.min(b.y) - pad, + a.x.max(b.x) + pad, + a.y.max(b.y) + pad, + ]); + for wire in candidates.iter() { + if !wire.display_visible + || wire.snap_only + || wire.point_marker.is_some() + || !wire.text_verts.is_empty() + { + continue; + } + let mut previous: Option = None; + for (index, point) in wire.points.iter().enumerate() { + if point[0].is_nan() || point[1].is_nan() { + previous = None; + continue; + } + let local = plane.to_local(wire.point_world(index, 0.0)); + if let Some(offset) = previous + .and_then(|previous| Self::crossing(previous, local, c, axis)) + .filter(|offset| offset.abs() > pad) + { + let slot = &mut hits[axis * 2 + usize::from(offset > 0.0)]; + if slot.is_none_or(|best: f64| offset.abs() < best.abs()) { + *slot = Some(offset); + } + } + previous = Some(local); + } + } + } + hits + } + + /// QUICK measurement lines (world) and readout for crossings `hits`. + fn quick_result( + plane: WorkingPlane, + cursor: DVec3, + hits: [Option; 4], + ) -> (Vec, Option) { + let c = plane.to_local(cursor); + let mut wires = Vec::new(); + let mut lines = Vec::new(); + for axis in 0..2 { + let (low, high) = (hits[axis * 2], hits[axis * 2 + 1]); + if low.is_none() && high.is_none() { + continue; + } + let (from, to) = (low.unwrap_or(0.0), high.unwrap_or(0.0)); + let mut start = c; + let mut end = c; + start[axis] += from; + end[axis] += to; + let f = |p: DVec3| { + let p = plane.to_world(p); + [p.x as f32, p.y as f32, p.z as f32] + }; + wires.push(Self::preview_wire( + "measuregeom_quick", + vec![f(start), f(end)], + )); + let value = crate::entities::common::format_length(to - from); + lines.push(if axis == 0 { + crate::tr!("measurement", "quick-horizontal", value = value) + } else { + crate::tr!("measurement", "quick-vertical", value = value) + }); + } + let readout = (!lines.is_empty()).then(|| lines.join("\n")); + (wires, readout) + } } impl CadCommand for MeasureGeomCommand { @@ -265,8 +380,9 @@ impl CadCommand for MeasureGeomCommand { fn prompt(&self) -> String { match self.mode { Mode::Choose => { - t!("MEASUREGEOM Enter an option [Distance/Radius/Angle/ARea]:").into_owned() + t!("MEASUREGEOM Enter an option [Quick/Distance/Radius/Angle/ARea]:").into_owned() } + Mode::Quick => return crate::tr!("measurement", "quick-prompt", command = self.name), Mode::Distance => { if self.points.is_empty() { t!("MEASUREGEOM Specify first point:").into_owned() @@ -322,6 +438,7 @@ impl CadCommand for MeasureGeomCommand { fn measurement_readout(&self, cursor: DVec3) -> Option { match self.mode { + Mode::Quick => self.quick.borrow().clone(), Mode::Distance if !self.points.is_empty() && cursor.is_finite() => Some(crate::tr!( "measurement", "distance", @@ -368,6 +485,10 @@ impl CadCommand for MeasureGeomCommand { }; } vec![ + CmdOption { + label: crate::tr!("measurement", "quick"), + keyword: "Q".into(), + }, CmdOption::new("Distance", "D"), CmdOption::new("Radius", "R"), CmdOption::new("Angle", "A"), @@ -397,6 +518,7 @@ impl CadCommand for MeasureGeomCommand { } let t = text.trim().to_uppercase(); self.mode = match t.as_str() { + "Q" | "QUICK" => Mode::Quick, "D" | "DISTANCE" => Mode::Distance, "R" | "RADIUS" => Mode::Radius, "A" | "ANGLE" => Mode::Angle, @@ -410,6 +532,30 @@ impl CadCommand for MeasureGeomCommand { matches!(self.mode, Mode::Radius | Mode::AngleLines) } + // QUICK reads the scene under the cursor; it never resolves an object, so + // every click lands in `on_point`. + fn needs_structure_point_pick(&self) -> bool { + self.mode == Mode::Quick + } + + fn object_pick_hover_previews( + &self, + scene: &crate::scene::Scene, + cursor: DVec3, + ) -> Vec { + if self.mode != Mode::Quick || !cursor.is_finite() { + return Vec::new(); + } + let hits = Self::quick_hits(scene, self.plane, cursor); + let (wires, readout) = Self::quick_result(self.plane, cursor, hits); + *self.quick.borrow_mut() = readout; + wires + } + + fn object_pick_miss_message(&self) -> &'static str { + "" + } + fn inject_before_entity_pick(&self) -> bool { true } @@ -468,6 +614,12 @@ impl CadCommand for MeasureGeomCommand { } fn on_point(&mut self, pt: DVec3) -> CmdResult { + if self.mode == Mode::Quick { + return match self.quick.borrow().clone() { + Some(text) => CmdResult::ReportMeasurement(text), + None => CmdResult::NeedPoint, + }; + } if matches!(self.mode, Mode::Distance | Mode::Angle | Mode::Area) && !pt.is_finite() { return CmdResult::ReportError(crate::tr!("measurement", "invalid-point")); } @@ -771,7 +923,7 @@ mod measurement_tests { #[test] fn measuregeom_all_four_modes_remain_available() { units(); - assert_eq!(MeasureGeomCommand::new().options().len(), 4); + assert_eq!(MeasureGeomCommand::new().options().len(), 5); let mut command = MeasureGeomCommand::new(); command.on_text_input("D"); command.on_point(DVec3::ZERO); diff --git a/src/scene/mod.rs b/src/scene/mod.rs index 9c425c08c..e5001d444 100644 --- a/src/scene/mod.rs +++ b/src/scene/mod.rs @@ -10150,6 +10150,20 @@ impl Scene { } } + /// Wires of the space being edited that may cross a world-XY box: the + /// indexed broad phase in model space, every wire elsewhere. + pub fn interaction_candidates_xy( + &self, + aabb: [f64; 4], + ) -> crate::scene::pick::interaction_index::InteractionCandidates { + let wires = self.hit_test_wires(); + if self.current_layout != "Model" || !self.interaction_index_worthwhile(&wires) { + return crate::scene::pick::interaction_index::InteractionCandidates::all(wires) + .materialize_stubs(); + } + self.indexed_interaction_candidates_xy(wires, aabb, false, false) + } + /// Small simple sets are cheaper to scan. Either many wires or substantial /// sub-geometry (one giant polyline/text batch/mesh) enables the index. const INTERACTION_INDEX_MIN_WIRES: usize = 4_000;