fix(dimension): complete angular workflow
This commit is contained in:
commit
649dfae337
35 changed files with 2082 additions and 262 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -72,7 +72,7 @@ checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618"
|
|||
[[package]]
|
||||
name = "acadrust"
|
||||
version = "0.4.1"
|
||||
source = "git+https://git@github.com/HakanSeven12/cadcodec.git?rev=5b2ae66#5b2ae66d0bd7b0da2d13392d3c3332f8a39caa1f"
|
||||
source = "git+https://git@github.com/HakanSeven12/cadcodec.git?rev=211f830#211f830e1478c2f38d22591957cc69a4d4dd1edc"
|
||||
dependencies = [
|
||||
"ahash 0.8.12",
|
||||
"anyhow",
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ glam = { version = "0.33", features = ["bytemuck"] }
|
|||
rfd = "0.17"
|
||||
clap = { version = "4", features = ["derive"] }
|
||||
env_logger = "0.11"
|
||||
acadrust = { git = "https://github.com/HakanSeven12/cadcodec.git", rev = "5b2ae66", features = ["serde"] }
|
||||
acadrust = { git = "https://github.com/HakanSeven12/cadcodec.git", rev = "211f830", features = ["serde"] }
|
||||
cadkernel = { git = "https://github.com/HakanSeven12/cadkernel.git", rev = "b2b1d4b", features = ["acis", "offset"] }
|
||||
dwg-thumbnailer = { path = "crates/dwg-thumbnailer" }
|
||||
flate2 = "1"
|
||||
|
|
@ -61,7 +61,7 @@ iced_core = { git = "https://github.com/iced-rs/iced.git", rev = "23604ff22ab0aa
|
|||
iced_widget = { git = "https://github.com/iced-rs/iced.git", rev = "23604ff22ab0aad9e00b9327cb7b8546ed84db39" }
|
||||
|
||||
[patch."https://github.com/HakanSeven12/cadcodec.git"]
|
||||
acadrust = { git = "https://git@github.com/HakanSeven12/cadcodec.git", rev = "5b2ae66" }
|
||||
acadrust = { git = "https://git@github.com/HakanSeven12/cadcodec.git", rev = "211f830" }
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
ocs_plugin_api = { path = "crates/ocs_plugin_api", features = ["host"] }
|
||||
|
|
|
|||
|
|
@ -1818,10 +1818,18 @@ annotate =
|
|||
.dimaligned-specify-first-extension-line-origin = DIMALIGNED حدد أصل خط الامتداد الأول أو اضغط Enter لتحديد كائن:
|
||||
.dimaligned-specify-second-extension-line-origi = DIMALIGNED حدد أصل خط الامتداد الثاني:
|
||||
.dimaligned-specify-text-angle-degrees = DIMALIGNED حدد زاوية النص (بالدرجات):
|
||||
.dimangular-enter-dimension-text-blank-measured = DIMANGULAR أدخل نص البُعد (فارغ = القيمة المقاسة):
|
||||
.dimangular-enter-formatted-dimension-text-blank-measured = DIMANGULAR أدخل نص البُعد المنسق (فارغ = القيمة المقاسة):
|
||||
.dimangular-select-arc-circle-line-or-specify-angle-vertex = DIMANGULAR حدد قوسًا أو دائرة أو خطًا، أو حدد رأس زاوية:
|
||||
.dimangular-select-second-line = DIMANGULAR حدد الخط الثاني:
|
||||
.dimangular-specify-angle-vertex = DIMANGULAR حدد رأس الزاوية:
|
||||
.dimangular-specify-dimension-arc-location-options = DIMANGULAR حدد موقع قوس البُعد [Mtext/نص/زاوية/ربع]:
|
||||
.dimangular-specify-dimension-arc-location = DIMANGULAR حدد موقع قوس البُعد:
|
||||
.dimangular-specify-first-extension-line-point = DIMANGULAR حدد نقطة خط الامتداد الأول:
|
||||
.dimangular-specify-quadrant = DIMANGULAR حدد الربع:
|
||||
.dimangular-specify-second-extension-line-point = DIMANGULAR حدد نقطة خط الامتداد الثاني:
|
||||
.dimangular-specify-second-point-for-text-angle = DIMANGULAR حدد النقطة الثانية لزاوية النص:
|
||||
.dimangular-specify-text-angle-or-first-point = DIMANGULAR حدد زاوية النص أو النقطة الأولى:
|
||||
.dimbaseline-no-base-dimension-found-place-a-di = DIMBASELINE لم يُعثر على بُعد أساسي. ضع بُعدًا أولًا.
|
||||
.dimbaseline-specify-a-second-extension-line-or = DIMBASELINE حدد أصل خط امتداد ثانٍ (Enter للخروج):
|
||||
.dimbreak-select-dimension-to-break = DIMBREAK حدد البُعد المراد قطعه:
|
||||
|
|
|
|||
|
|
@ -1805,10 +1805,18 @@ annotate =
|
|||
.dimaligned-specify-first-extension-line-origin = DIMALIGNED Посочи начало на първата удължителна линия или натисни Enter за избор на обект:
|
||||
.dimaligned-specify-second-extension-line-origi = DIMALIGNED Посочи начало на втората удължителна линия:
|
||||
.dimaligned-specify-text-angle-degrees = DIMALIGNED Посочи ъгъл на текста (градуси):
|
||||
.dimangular-enter-dimension-text-blank-measured = DIMANGULAR Въведи текст на оразмеряване (празно = измерена стойност):
|
||||
.dimangular-enter-formatted-dimension-text-blank-measured = DIMANGULAR Въведи форматиран текст на оразмеряване (празно = измерена стойност):
|
||||
.dimangular-select-arc-circle-line-or-specify-angle-vertex = DIMANGULAR Избери дъга, окръжност, линия или посочи връх на ъгъла:
|
||||
.dimangular-select-second-line = DIMANGULAR Избери втората линия:
|
||||
.dimangular-specify-angle-vertex = DIMANGULAR Посочи връх на ъгъла:
|
||||
.dimangular-specify-dimension-arc-location-options = DIMANGULAR Посочи местоположение на дъгата за оразмеряване [Mtext/Текст/Ъгъл/Квадрант]:
|
||||
.dimangular-specify-dimension-arc-location = DIMANGULAR Посочи местоположение на дъгата за оразмеряване:
|
||||
.dimangular-specify-first-extension-line-point = DIMANGULAR Посочи точка на първата удължителна линия:
|
||||
.dimangular-specify-quadrant = DIMANGULAR Посочи квадрант:
|
||||
.dimangular-specify-second-extension-line-point = DIMANGULAR Посочи точка на втората удължителна линия:
|
||||
.dimangular-specify-second-point-for-text-angle = DIMANGULAR Посочи втора точка за ъгъла на текста:
|
||||
.dimangular-specify-text-angle-or-first-point = DIMANGULAR Посочи ъгъл на текста или първа точка:
|
||||
.dimbaseline-no-base-dimension-found-place-a-di = DIMBASELINE Не е намерено базово оразмеряване. Първо постави оразмеряване.
|
||||
.dimbaseline-specify-a-second-extension-line-or = DIMBASELINE Посочи начало на втора удължителна линия (Enter за изход):
|
||||
.dimbreak-select-dimension-to-break = DIMBREAK Избери оразмеряване за прекъсване:
|
||||
|
|
|
|||
|
|
@ -1805,10 +1805,18 @@ annotate =
|
|||
.dimaligned-specify-first-extension-line-origin = DIMALIGNED Zadejte počátek první vynášecí čáry nebo stiskněte Enter pro výběr objektu:
|
||||
.dimaligned-specify-second-extension-line-origi = DIMALIGNED Zadejte počátek druhé vynášecí čáry:
|
||||
.dimaligned-specify-text-angle-degrees = DIMALIGNED Zadejte úhel textu (stupně):
|
||||
.dimangular-enter-dimension-text-blank-measured = DIMANGULAR Zadejte text kóty (prázdné = naměřená hodnota):
|
||||
.dimangular-enter-formatted-dimension-text-blank-measured = DIMANGULAR Zadejte formátovaný text kóty (prázdné = naměřená hodnota):
|
||||
.dimangular-select-arc-circle-line-or-specify-angle-vertex = DIMANGULAR Vyberte oblouk, kružnici či čáru, nebo zadejte vrchol úhlu:
|
||||
.dimangular-select-second-line = DIMANGULAR Vyberte druhou čáru:
|
||||
.dimangular-specify-angle-vertex = DIMANGULAR Zadejte vrchol úhlu:
|
||||
.dimangular-specify-dimension-arc-location-options = DIMANGULAR Zadejte umístění oblouku kóty [Mtext/Text/Úhel/Kvadrant]:
|
||||
.dimangular-specify-dimension-arc-location = DIMANGULAR Zadejte umístění oblouku kóty:
|
||||
.dimangular-specify-first-extension-line-point = DIMANGULAR Zadejte první bod vynášecí čáry:
|
||||
.dimangular-specify-quadrant = DIMANGULAR Zadejte kvadrant:
|
||||
.dimangular-specify-second-extension-line-point = DIMANGULAR Zadejte druhý bod vynášecí čáry:
|
||||
.dimangular-specify-second-point-for-text-angle = DIMANGULAR Zadejte druhý bod úhlu textu:
|
||||
.dimangular-specify-text-angle-or-first-point = DIMANGULAR Zadejte úhel textu nebo první bod:
|
||||
.dimbaseline-no-base-dimension-found-place-a-di = DIMBASELINE Nebyl nalezen žádný rozměr základny. Nejprve umístěte kótu.
|
||||
.dimbaseline-specify-a-second-extension-line-or = DIMBASELINE Zadejte počátek druhé prodlužovací čáry (Enter pro ukončení):
|
||||
.dimbreak-select-dimension-to-break = DIMBREAK Vyberte rozměr, který chcete přerušit:
|
||||
|
|
|
|||
|
|
@ -1806,10 +1806,18 @@ annotate =
|
|||
.dimaligned-specify-first-extension-line-origin = DIMALIGNED Ursprung der ersten Maßhilfslinie angeben oder Enter drücken, um ein Objekt auszuwählen:
|
||||
.dimaligned-specify-second-extension-line-origi = DIMALIGNED Ursprung der zweiten Maßhilfslinie angeben:
|
||||
.dimaligned-specify-text-angle-degrees = DIMALIGNED Textwinkel angeben (Grad):
|
||||
.dimangular-enter-dimension-text-blank-measured = DIMANGULAR Bemaßungstext eingeben (leer = Messwert):
|
||||
.dimangular-enter-formatted-dimension-text-blank-measured = DIMANGULAR Formatierten Bemaßungstext eingeben (leer = Messwert):
|
||||
.dimangular-select-arc-circle-line-or-specify-angle-vertex = DIMANGULAR Bogen, Kreis oder Linie wählen oder Winkelspitze angeben:
|
||||
.dimangular-select-second-line = DIMANGULAR Zweite Linie wählen:
|
||||
.dimangular-specify-angle-vertex = DIMANGULAR Winkelspitze angeben:
|
||||
.dimangular-specify-dimension-arc-location-options = DIMANGULAR Bemaßungsbogenlage angeben [Mtext/Text/Winkel/Quadrant]:
|
||||
.dimangular-specify-dimension-arc-location = DIMANGULAR Bemaßungsbogenlage angeben:
|
||||
.dimangular-specify-first-extension-line-point = DIMANGULAR Geben Sie den ersten Verlängerungslinienpunkt an:
|
||||
.dimangular-specify-quadrant = DIMANGULAR Quadrant angeben:
|
||||
.dimangular-specify-second-extension-line-point = DIMANGULAR Zweiter Verlängerungslinienpunkt angeben:
|
||||
.dimangular-specify-second-point-for-text-angle = DIMANGULAR Zweiten Punkt für Textwinkel angeben:
|
||||
.dimangular-specify-text-angle-or-first-point = DIMANGULAR Textwinkel oder ersten Punkt angeben:
|
||||
.dimbaseline-no-base-dimension-found-place-a-di = DIMBASELINE Keine Basisdimension gefunden.
|
||||
.dimbaseline-specify-a-second-extension-line-or = DIMBASELINE Ursprung der zweiten Maßhilfslinie angeben (Eingabe zum Beenden):
|
||||
.dimbreak-select-dimension-to-break = DIMBREAK Bemaßung auswählen, um zu brechen:
|
||||
|
|
|
|||
|
|
@ -1836,10 +1836,18 @@ annotate =
|
|||
.dimaligned-specify-first-extension-line-origin = DIMALIGNED Specify first extension line origin or press Enter to select object:
|
||||
.dimaligned-specify-second-extension-line-origi = DIMALIGNED Specify second extension line origin:
|
||||
.dimaligned-specify-text-angle-degrees = DIMALIGNED Specify text angle (degrees):
|
||||
.dimangular-enter-dimension-text-blank-measured = DIMANGULAR Enter dimension text (blank = measured value):
|
||||
.dimangular-enter-formatted-dimension-text-blank-measured = DIMANGULAR Enter formatted dimension text (blank = measured value):
|
||||
.dimangular-select-arc-circle-line-or-specify-angle-vertex = DIMANGULAR Select arc, circle, line, or specify an angle vertex:
|
||||
.dimangular-select-second-line = DIMANGULAR Select second line:
|
||||
.dimangular-specify-angle-vertex = DIMANGULAR Specify angle vertex:
|
||||
.dimangular-specify-dimension-arc-location-options = DIMANGULAR Specify dimension arc location [Mtext/Text/Angle/Quadrant]:
|
||||
.dimangular-specify-dimension-arc-location = DIMANGULAR Specify dimension arc location:
|
||||
.dimangular-specify-first-extension-line-point = DIMANGULAR Specify first extension line point:
|
||||
.dimangular-specify-quadrant = DIMANGULAR Specify quadrant:
|
||||
.dimangular-specify-second-extension-line-point = DIMANGULAR Specify second extension line point:
|
||||
.dimangular-specify-second-point-for-text-angle = DIMANGULAR Specify second point for text angle:
|
||||
.dimangular-specify-text-angle-or-first-point = DIMANGULAR Specify text angle or first point:
|
||||
.dimbaseline-no-base-dimension-found-place-a-di = DIMBASELINE No base dimension found. Place a dimension first.
|
||||
.dimbaseline-specify-a-second-extension-line-or = DIMBASELINE Specify a second extension line origin (Enter to exit):
|
||||
.dimbreak-select-dimension-to-break = DIMBREAK Select dimension to break:
|
||||
|
|
|
|||
|
|
@ -1806,10 +1806,18 @@ annotate =
|
|||
.dimaligned-specify-first-extension-line-origin = DIMALIGNED Especifique el origen de la primera línea de referencia o pulse Enter para seleccionar un objeto:
|
||||
.dimaligned-specify-second-extension-line-origi = DIMALIGNED Especifique el origen de la segunda línea de referencia:
|
||||
.dimaligned-specify-text-angle-degrees = DIMALIGNED Especifique el ángulo del texto (grados):
|
||||
.dimangular-enter-dimension-text-blank-measured = DIMANGULAR Introduzca el texto de cota (vacío = valor medido):
|
||||
.dimangular-enter-formatted-dimension-text-blank-measured = DIMANGULAR Introduzca el texto de cota con formato (vacío = valor medido):
|
||||
.dimangular-select-arc-circle-line-or-specify-angle-vertex = DIMANGULAR Seleccione arco, círculo, línea o especifique un vértice de ángulo:
|
||||
.dimangular-select-second-line = DIMANGULAR Seleccione la segunda línea:
|
||||
.dimangular-specify-angle-vertex = DIMANGULAR Especifique el vértice del ángulo:
|
||||
.dimangular-specify-dimension-arc-location-options = DIMANGULAR Especifique la ubicación del arco de cota [Mtext/Texto/Ángulo/Cuadrante]:
|
||||
.dimangular-specify-dimension-arc-location = DIMANGULAR Especifique la ubicación del arco de cota:
|
||||
.dimangular-specify-first-extension-line-point = DIMANGULAR Especifique un punto de la primera línea de referencia:
|
||||
.dimangular-specify-quadrant = DIMANGULAR Especifique el cuadrante:
|
||||
.dimangular-specify-second-extension-line-point = DIMANGULAR Especifique un punto de la segunda línea de referencia:
|
||||
.dimangular-specify-second-point-for-text-angle = DIMANGULAR Especifique el segundo punto para el ángulo del texto:
|
||||
.dimangular-specify-text-angle-or-first-point = DIMANGULAR Especifique el ángulo del texto o el primer punto:
|
||||
.dimbaseline-no-base-dimension-found-place-a-di = DIMBASELINE No se encontró ninguna cota base. Coloque primero una cota.
|
||||
.dimbaseline-specify-a-second-extension-line-or = DIMBASELINE Especifique el origen de una segunda línea de referencia (Enter para salir):
|
||||
.dimbreak-select-dimension-to-break = DIMBREAK Seleccione la cota que desea partir:
|
||||
|
|
|
|||
|
|
@ -1805,10 +1805,18 @@ annotate =
|
|||
.dimaligned-specify-first-extension-line-origin = DIMALIGNED Määritä ensimmäisen apuviivan alkupiste tai valitse objekti painamalla Enter:
|
||||
.dimaligned-specify-second-extension-line-origi = DIMALIGNED Määritä toisen apuviivan alkupiste:
|
||||
.dimaligned-specify-text-angle-degrees = DIMALIGNED Määritä tekstin kulma (asteita):
|
||||
.dimangular-enter-dimension-text-blank-measured = DIMANGULAR Syötä mittateksti (tyhjä = mitattu arvo):
|
||||
.dimangular-enter-formatted-dimension-text-blank-measured = DIMANGULAR Syötä muotoiltu mittateksti (tyhjä = mitattu arvo):
|
||||
.dimangular-select-arc-circle-line-or-specify-angle-vertex = DIMANGULAR Valitse kaari, ympyrä tai viiva tai määritä kulman kärkipiste:
|
||||
.dimangular-select-second-line = DIMANGULAR Valitse toinen viiva:
|
||||
.dimangular-specify-angle-vertex = DIMANGULAR Määritä kulman kärkipiste:
|
||||
.dimangular-specify-dimension-arc-location-options = DIMANGULAR Määritä mittakaaren sijainti [Mtext/Teksti/Kulma/Neljännes]:
|
||||
.dimangular-specify-dimension-arc-location = DIMANGULAR Määritä mittakaaren sijainti:
|
||||
.dimangular-specify-first-extension-line-point = DIMANGULAR Määritä ensimmäinen jatkolinjan piste:
|
||||
.dimangular-specify-quadrant = DIMANGULAR Määritä neljännes:
|
||||
.dimangular-specify-second-extension-line-point = DIMANGULAR Määritä toinen jatkolinjan piste:
|
||||
.dimangular-specify-second-point-for-text-angle = DIMANGULAR Määritä tekstikulman toinen piste:
|
||||
.dimangular-specify-text-angle-or-first-point = DIMANGULAR Määritä tekstikulma tai ensimmäinen piste:
|
||||
.dimbaseline-no-base-dimension-found-place-a-di = DIMBASELINE Perusmittaa ei löytynyt. Aseta ensin mitta.
|
||||
.dimbaseline-specify-a-second-extension-line-or = DIMBASELINE Määritä toinen alalinjan lähtökohta (Enter poistuaksesi):
|
||||
.dimbreak-select-dimension-to-break = DIMBREAK Valitse katkaistava mitta:
|
||||
|
|
|
|||
|
|
@ -1806,10 +1806,18 @@ annotate =
|
|||
.dimaligned-specify-first-extension-line-origin = DIMALIGNED Spécifiez l'origine de la première ligne d'attache ou appuyez sur Entrée pour sélectionner un objet :
|
||||
.dimaligned-specify-second-extension-line-origi = DIMALIGNED Spécifiez l'origine de la deuxième ligne d'attache :
|
||||
.dimaligned-specify-text-angle-degrees = DIMALIGNED Spécifiez l'angle de texte (degrés):
|
||||
.dimangular-enter-dimension-text-blank-measured = DIMANGULAR Saisissez le texte de cote (vide = valeur mesurée) :
|
||||
.dimangular-enter-formatted-dimension-text-blank-measured = DIMANGULAR Saisissez le texte de cote formaté (vide = valeur mesurée) :
|
||||
.dimangular-select-arc-circle-line-or-specify-angle-vertex = DIMANGULAR Sélectionnez un arc, un cercle ou une ligne, ou spécifiez un sommet d'angle :
|
||||
.dimangular-select-second-line = DIMANGULAR Sélectionnez la deuxième ligne :
|
||||
.dimangular-specify-angle-vertex = DIMANGULAR Spécifiez le sommet d'angle:
|
||||
.dimangular-specify-dimension-arc-location-options = DIMANGULAR Spécifiez l'emplacement de l'arc de cote [Mtext/Texte/Angle/Quadrant] :
|
||||
.dimangular-specify-dimension-arc-location = DIMANGULAR Spécifier l'emplacement de l'arc dimensionnel:
|
||||
.dimangular-specify-first-extension-line-point = DIMANGULAR Spécifiez le premier point de ligne d'extension:
|
||||
.dimangular-specify-quadrant = DIMANGULAR Spécifiez le quadrant :
|
||||
.dimangular-specify-second-extension-line-point = DIMANGULAR Spécifiez le deuxième point de la ligne d'extension:
|
||||
.dimangular-specify-second-point-for-text-angle = DIMANGULAR Spécifiez le deuxième point pour l'angle du texte :
|
||||
.dimangular-specify-text-angle-or-first-point = DIMANGULAR Spécifiez l'angle du texte ou le premier point :
|
||||
.dimbaseline-no-base-dimension-found-place-a-di = DIMBASELINE Aucune cote de base trouvée. Créez d’abord une cote.
|
||||
.dimbaseline-specify-a-second-extension-line-or = DIMBASELINE Spécifiez une deuxième ligne d'extension d'origine (Entrer pour sortir):
|
||||
.dimbreak-select-dimension-to-break = DIMBREAK Sélectionnez la dimension à casser:
|
||||
|
|
|
|||
|
|
@ -1794,10 +1794,18 @@ annotate =
|
|||
.dimaligned-specify-first-extension-line-origin = DIMALIGNED पहली एक्सटेंशन रेखा का मूल निर्दिष्ट करें या ऑब्जेक्ट चुनने के लिए Enter दबाएँ:
|
||||
.dimaligned-specify-second-extension-line-origi = DIMALIGNED दूसरी एक्सटेंशन रेखा का मूल निर्दिष्ट करें:
|
||||
.dimaligned-specify-text-angle-degrees = DIMALIGNED पाठ कोण निर्दिष्ट करें (डिग्री):
|
||||
.dimangular-enter-dimension-text-blank-measured = DIMANGULAR आयाम टेक्स्ट दर्ज करें (खाली = मापा मान):
|
||||
.dimangular-enter-formatted-dimension-text-blank-measured = DIMANGULAR स्वरूपित आयाम टेक्स्ट दर्ज करें (खाली = मापा मान):
|
||||
.dimangular-select-arc-circle-line-or-specify-angle-vertex = DIMANGULAR चाप, वृत्त या रेखा चुनें, या कोण का शीर्ष निर्दिष्ट करें:
|
||||
.dimangular-select-second-line = DIMANGULAR दूसरी रेखा चुनें:
|
||||
.dimangular-specify-angle-vertex = DIMANGULAR कोण वर्टेक्स निर्दिष्ट करें:
|
||||
.dimangular-specify-dimension-arc-location-options = DIMANGULAR आयाम आर्क स्थान निर्दिष्ट करें [Mtext/टेक्स्ट/कोण/चतुर्थांश]:
|
||||
.dimangular-specify-dimension-arc-location = DIMANGULAR आयाम आर्क स्थान निर्दिष्ट करें:
|
||||
.dimangular-specify-first-extension-line-point = DIMANGULAR पहली एक्सटेंशन लाइन बिंदु निर्दिष्ट करें:
|
||||
.dimangular-specify-quadrant = DIMANGULAR चतुर्थांश निर्दिष्ट करें:
|
||||
.dimangular-specify-second-extension-line-point = DIMANGULAR दूसरी एक्सटेंशन लाइन बिंदु निर्दिष्ट करें:
|
||||
.dimangular-specify-second-point-for-text-angle = DIMANGULAR टेक्स्ट कोण के लिए दूसरा बिंदु निर्दिष्ट करें:
|
||||
.dimangular-specify-text-angle-or-first-point = DIMANGULAR टेक्स्ट कोण या पहला बिंदु निर्दिष्ट करें:
|
||||
.dimbaseline-no-base-dimension-found-place-a-di = DIMBASELINE कोई आधार आयाम नहीं मिला। पहले आयाम दें।
|
||||
.dimbaseline-specify-a-second-extension-line-or = DIMBASELINE एक दूसरी विस्तार लाइन मूल निर्दिष्ट करें (बाहर निकलने के लिए बेहतर):
|
||||
.dimbreak-select-dimension-to-break = DIMBREAK तोड़ने के लिए आयाम का चयन करें:
|
||||
|
|
|
|||
|
|
@ -1805,10 +1805,18 @@ annotate =
|
|||
.dimaligned-specify-first-extension-line-origin = DIMALIGNED Adja meg az első segédvonal kezdőpontját, vagy nyomja meg az Entert egy objektum kiválasztásához:
|
||||
.dimaligned-specify-second-extension-line-origi = DIMALIGNED Adja meg a második segédvonal kezdőpontját:
|
||||
.dimaligned-specify-text-angle-degrees = DIMALIGNED Adja meg a szöveg szögét (fokban):
|
||||
.dimangular-enter-dimension-text-blank-measured = DIMANGULAR Adja meg a méretszöveget (üres = mért érték):
|
||||
.dimangular-enter-formatted-dimension-text-blank-measured = DIMANGULAR Adja meg a formázott méretszöveget (üres = mért érték):
|
||||
.dimangular-select-arc-circle-line-or-specify-angle-vertex = DIMANGULAR Válasszon ívet, kört vagy vonalat, vagy adjon meg egy szögcsúcsot:
|
||||
.dimangular-select-second-line = DIMANGULAR Válassza ki a második vonalat:
|
||||
.dimangular-specify-angle-vertex = DIMANGULAR Szögcsúcs megadása:
|
||||
.dimangular-specify-dimension-arc-location-options = DIMANGULAR Adja meg a méretív helyét [Mtext/Szöveg/Szög/Kvadráns]:
|
||||
.dimangular-specify-dimension-arc-location = DIMANGULAR A méretív helyének megadása:
|
||||
.dimangular-specify-first-extension-line-point = DIMANGULAR Adja meg az első hosszabbító vonalpontot:
|
||||
.dimangular-specify-quadrant = DIMANGULAR Adja meg a kvadránst:
|
||||
.dimangular-specify-second-extension-line-point = DIMANGULAR Adja meg a második kiterjesztési vonalpontot:
|
||||
.dimangular-specify-second-point-for-text-angle = DIMANGULAR Adja meg a szövegszög második pontját:
|
||||
.dimangular-specify-text-angle-or-first-point = DIMANGULAR Adja meg a szövegszöget vagy az első pontot:
|
||||
.dimbaseline-no-base-dimension-found-place-a-di = DIMBASELINE Nem található alapméret. Először helyezzen el egy méretet.
|
||||
.dimbaseline-specify-a-second-extension-line-or = DIMBASELINE Adjon meg egy második mellékvonal kezdőpontját (Enter a kilépéshez):
|
||||
.dimbreak-select-dimension-to-break = DIMBREAK Válassza ki a törni kívánt méretet:
|
||||
|
|
|
|||
|
|
@ -1805,10 +1805,18 @@ annotate =
|
|||
.dimaligned-specify-first-extension-line-origin = DIMALIGNED Specificare l'origine della prima linea di estensione o premere Invio per selezionare un oggetto:
|
||||
.dimaligned-specify-second-extension-line-origi = DIMALIGNED Specificare l'origine della seconda linea di estensione:
|
||||
.dimaligned-specify-text-angle-degrees = DIMALIGNED Specificare l'angolo del testo (gradi):
|
||||
.dimangular-enter-dimension-text-blank-measured = DIMANGULAR Immettere il testo di quota (vuoto = valore misurato):
|
||||
.dimangular-enter-formatted-dimension-text-blank-measured = DIMANGULAR Immettere il testo di quota formattato (vuoto = valore misurato):
|
||||
.dimangular-select-arc-circle-line-or-specify-angle-vertex = DIMANGULAR Selezionare un arco, un cerchio o una linea oppure specificare un vertice dell'angolo:
|
||||
.dimangular-select-second-line = DIMANGULAR Selezionare la seconda linea:
|
||||
.dimangular-specify-angle-vertex = DIMANGULAR Specificare il vertice dell'angolo:
|
||||
.dimangular-specify-dimension-arc-location-options = DIMANGULAR Specificare la posizione dell'arco di quota [Mtext/Testo/Angolo/Quadrante]:
|
||||
.dimangular-specify-dimension-arc-location = DIMANGULAR Specificare la posizione dell'arco di quota:
|
||||
.dimangular-specify-first-extension-line-point = DIMANGULAR Specificare il primo punto della linea di estensione:
|
||||
.dimangular-specify-quadrant = DIMANGULAR Specificare il quadrante:
|
||||
.dimangular-specify-second-extension-line-point = DIMANGULAR Specificare il secondo punto della linea di estensione:
|
||||
.dimangular-specify-second-point-for-text-angle = DIMANGULAR Specificare il secondo punto per l'angolo del testo:
|
||||
.dimangular-specify-text-angle-or-first-point = DIMANGULAR Specificare l'angolo del testo o il primo punto:
|
||||
.dimbaseline-no-base-dimension-found-place-a-di = DIMBASELINE Nessuna dimensione base trovata. Posiziona prima una dimensione.
|
||||
.dimbaseline-specify-a-second-extension-line-or = DIMBASELINE Specificare una seconda origine della linea di estensione (Enter per uscire):
|
||||
.dimbreak-select-dimension-to-break = DIMBREAK Selezionare la dimensione da interrompere:
|
||||
|
|
|
|||
|
|
@ -1796,10 +1796,18 @@ annotate =
|
|||
.dimaligned-specify-first-extension-line-origin = DIMALIGNED 1 本目の寸法補助線の起点を指定、または Enter でオブジェクトを選択:
|
||||
.dimaligned-specify-second-extension-line-origi = DIMALIGNED 2 本目の寸法補助線の起点を指定:
|
||||
.dimaligned-specify-text-angle-degrees = DIMALIGNED 文字角度を指定(度):
|
||||
.dimangular-enter-dimension-text-blank-measured = DIMANGULAR 寸法値を入力(空白 = 計測値):
|
||||
.dimangular-enter-formatted-dimension-text-blank-measured = DIMANGULAR 書式付き寸法文字を入力(空白 = 計測値):
|
||||
.dimangular-select-arc-circle-line-or-specify-angle-vertex = DIMANGULAR 円弧、円、線分を選択、または角度の頂点を指定:
|
||||
.dimangular-select-second-line = DIMANGULAR 2 本目の線分を選択:
|
||||
.dimangular-specify-angle-vertex = DIMANGULAR 角度の頂点を指定:
|
||||
.dimangular-specify-dimension-arc-location-options = DIMANGULAR 寸法円弧の位置を指定 [Mtext/文字/角度/象限]:
|
||||
.dimangular-specify-dimension-arc-location = DIMANGULAR 寸法円弧の位置を指定:
|
||||
.dimangular-specify-first-extension-line-point = DIMANGULAR 1 本目の寸法補助線の点を指定:
|
||||
.dimangular-specify-quadrant = DIMANGULAR 象限を指定:
|
||||
.dimangular-specify-second-extension-line-point = DIMANGULAR 2 本目の寸法補助線の点を指定:
|
||||
.dimangular-specify-second-point-for-text-angle = DIMANGULAR 文字角度の 2 点目を指定:
|
||||
.dimangular-specify-text-angle-or-first-point = DIMANGULAR 文字角度または 1 点目を指定:
|
||||
.dimbaseline-no-base-dimension-found-place-a-di = DIMBASELINE 基準寸法がありません。先に寸法を配置してください。
|
||||
.dimbaseline-specify-a-second-extension-line-or = DIMBASELINE 2 本目の寸法補助線の起点を指定(Enter で終了):
|
||||
.dimbreak-select-dimension-to-break = DIMBREAK 分割する寸法を選択:
|
||||
|
|
|
|||
|
|
@ -1805,10 +1805,18 @@ annotate =
|
|||
.dimaligned-specify-first-extension-line-origin = DIMALIGNED 첫 번째 치수 보조선 원점을 지정하거나 Enter를 눌러 객체 선택:
|
||||
.dimaligned-specify-second-extension-line-origi = DIMALIGNED 두 번째 치수 보조선 원점 지정:
|
||||
.dimaligned-specify-text-angle-degrees = DIMALIGNED 텍스트 각도(도) 지정:
|
||||
.dimangular-enter-dimension-text-blank-measured = DIMANGULAR 치수 문자를 입력하십시오(비워 두면 측정값):
|
||||
.dimangular-enter-formatted-dimension-text-blank-measured = DIMANGULAR 서식 있는 치수 문자를 입력하십시오(비워 두면 측정값):
|
||||
.dimangular-select-arc-circle-line-or-specify-angle-vertex = DIMANGULAR 호, 원 또는 선을 선택하거나 각도 꼭지점을 지정하십시오:
|
||||
.dimangular-select-second-line = DIMANGULAR 두 번째 선을 선택하십시오:
|
||||
.dimangular-specify-angle-vertex = DIMANGULAR 각도 꼭지점 지정:
|
||||
.dimangular-specify-dimension-arc-location-options = DIMANGULAR 치수 호 위치 지정 [Mtext/문자/각도/사분면]:
|
||||
.dimangular-specify-dimension-arc-location = DIMANGULAR 치수 호 위치를 지정합니다.
|
||||
.dimangular-specify-first-extension-line-point = DIMANGULAR 첫 번째 연장선 점 지정:
|
||||
.dimangular-specify-quadrant = DIMANGULAR 사분면을 지정하십시오:
|
||||
.dimangular-specify-second-extension-line-point = DIMANGULAR 두 번째 연장선 점을 지정합니다.
|
||||
.dimangular-specify-second-point-for-text-angle = DIMANGULAR 문자 각도의 두 번째 점을 지정하십시오:
|
||||
.dimangular-specify-text-angle-or-first-point = DIMANGULAR 문자 각도 또는 첫 번째 점을 지정하십시오:
|
||||
.dimbaseline-no-base-dimension-found-place-a-di = DIMBASELINE 기본 치수를 찾을 수 없습니다. 먼저 치수를 배치합니다.
|
||||
.dimbaseline-specify-a-second-extension-line-or = DIMBASELINE 두 번째 연장선 원점을 지정합니다(종료하려면 Enter).
|
||||
.dimbreak-select-dimension-to-break = DIMBREAK 끊을 치수 선택:
|
||||
|
|
|
|||
|
|
@ -1806,10 +1806,18 @@ annotate =
|
|||
.dimaligned-specify-first-extension-line-origin = DIMALIGNED Geef het beginpunt van de eerste hulplijn op of druk op Enter om een object te selecteren:
|
||||
.dimaligned-specify-second-extension-line-origi = DIMALIGNED Geef het beginpunt van de tweede hulplijn op:
|
||||
.dimaligned-specify-text-angle-degrees = DIMALIGNED Teksthoek (graden) specificeren:
|
||||
.dimangular-enter-dimension-text-blank-measured = DIMANGULAR Voer maattekst in (leeg = gemeten waarde):
|
||||
.dimangular-enter-formatted-dimension-text-blank-measured = DIMANGULAR Voer opgemaakte maattekst in (leeg = gemeten waarde):
|
||||
.dimangular-select-arc-circle-line-or-specify-angle-vertex = DIMANGULAR Selecteer een boog, cirkel of lijn, of geef een hoekpunt op:
|
||||
.dimangular-select-second-line = DIMANGULAR Selecteer de tweede lijn:
|
||||
.dimangular-specify-angle-vertex = DIMANGULAR Specificeer hoekvertex:
|
||||
.dimangular-specify-dimension-arc-location-options = DIMANGULAR Geef de positie van de maatboog op [Mtext/Tekst/Hoek/Kwadrant]:
|
||||
.dimangular-specify-dimension-arc-location = DIMANGULAR Geef de positie van de maatboog op:
|
||||
.dimangular-specify-first-extension-line-point = DIMANGULAR Geef eerste extensieregelpunt aan:
|
||||
.dimangular-specify-quadrant = DIMANGULAR Geef het kwadrant op:
|
||||
.dimangular-specify-second-extension-line-point = DIMANGULAR Geef tweede extensieregelpunt:
|
||||
.dimangular-specify-second-point-for-text-angle = DIMANGULAR Geef het tweede punt voor de teksthoek op:
|
||||
.dimangular-specify-text-angle-or-first-point = DIMANGULAR Geef de teksthoek of het eerste punt op:
|
||||
.dimbaseline-no-base-dimension-found-place-a-di = DIMBASELINE Geen basismaat gevonden. Plaats eerst een maat.
|
||||
.dimbaseline-specify-a-second-extension-line-or = DIMBASELINE Vermeld een tweede extensielijn (tot afsluiten overgaan):
|
||||
.dimbreak-select-dimension-to-break = DIMBREAK Selecteer de te onderbreken maat:
|
||||
|
|
|
|||
|
|
@ -1805,10 +1805,18 @@ annotate =
|
|||
.dimaligned-specify-first-extension-line-origin = DIMALIGNED Określ początek pierwszej linii pomocniczej lub naciśnij Enter, aby wybrać obiekt:
|
||||
.dimaligned-specify-second-extension-line-origi = DIMALIGNED Określ początek drugiej linii pomocniczej:
|
||||
.dimaligned-specify-text-angle-degrees = DIMALIGNED Określ kąt tekstu (w stopniach):
|
||||
.dimangular-enter-dimension-text-blank-measured = DIMANGULAR Wprowadź tekst wymiaru (puste = zmierzona wartość):
|
||||
.dimangular-enter-formatted-dimension-text-blank-measured = DIMANGULAR Wprowadź sformatowany tekst wymiaru (puste = zmierzona wartość):
|
||||
.dimangular-select-arc-circle-line-or-specify-angle-vertex = DIMANGULAR Wybierz łuk, okrąg lub linię albo określ wierzchołek kąta:
|
||||
.dimangular-select-second-line = DIMANGULAR Wybierz drugą linię:
|
||||
.dimangular-specify-angle-vertex = DIMANGULAR Określ wierzchołek kąta:
|
||||
.dimangular-specify-dimension-arc-location-options = DIMANGULAR Określ położenie łuku wymiarowego [Mtext/Tekst/Kąt/Ćwiartka]:
|
||||
.dimangular-specify-dimension-arc-location = DIMANGULAR Określ położenie łuku wymiarowego:
|
||||
.dimangular-specify-first-extension-line-point = DIMANGULAR Określ pierwszy punkt linii pomocniczej:
|
||||
.dimangular-specify-quadrant = DIMANGULAR Określ ćwiartkę:
|
||||
.dimangular-specify-second-extension-line-point = DIMANGULAR Określ drugi punkt linii pomocniczej:
|
||||
.dimangular-specify-second-point-for-text-angle = DIMANGULAR Określ drugi punkt kąta tekstu:
|
||||
.dimangular-specify-text-angle-or-first-point = DIMANGULAR Określ kąt tekstu lub pierwszy punkt:
|
||||
.dimbaseline-no-base-dimension-found-place-a-di = DIMBASELINE Nie znaleziono wymiaru podstawowego. Najpierw umieść wymiar.
|
||||
.dimbaseline-specify-a-second-extension-line-or = DIMBASELINE Określ początek drugiej linii pomocniczej (Enter, aby wyjść):
|
||||
.dimbreak-select-dimension-to-break = DIMBREAK Wybierz wymiar do przerwania:
|
||||
|
|
|
|||
|
|
@ -1806,10 +1806,18 @@ annotate =
|
|||
.dimaligned-specify-first-extension-line-origin = DIMALIGNED Especifique a origem da primeira linha de extensão ou pressione Enter para selecionar um objeto:
|
||||
.dimaligned-specify-second-extension-line-origi = DIMALIGNED Especifique a origem da segunda linha de extensão:
|
||||
.dimaligned-specify-text-angle-degrees = DIMALIGNED Especifique o ângulo do texto (graus):
|
||||
.dimangular-enter-dimension-text-blank-measured = DIMANGULAR Insira o texto da cota (vazio = valor medido):
|
||||
.dimangular-enter-formatted-dimension-text-blank-measured = DIMANGULAR Insira o texto formatado da cota (vazio = valor medido):
|
||||
.dimangular-select-arc-circle-line-or-specify-angle-vertex = DIMANGULAR Selecione arco, círculo, linha ou especifique um vértice de ângulo:
|
||||
.dimangular-select-second-line = DIMANGULAR Selecione a segunda linha:
|
||||
.dimangular-specify-angle-vertex = DIMANGULAR Especifique o vértice do ângulo:
|
||||
.dimangular-specify-dimension-arc-location-options = DIMANGULAR Especifique a localização do arco de cota [Mtext/Texto/Ângulo/Quadrante]:
|
||||
.dimangular-specify-dimension-arc-location = DIMANGULAR Especifique a localização do arco de cota:
|
||||
.dimangular-specify-first-extension-line-point = DIMANGULAR Especifique o ponto da primeira linha de extensão:
|
||||
.dimangular-specify-quadrant = DIMANGULAR Especifique o quadrante:
|
||||
.dimangular-specify-second-extension-line-point = DIMANGULAR Especifique o ponto da segunda linha de extensão:
|
||||
.dimangular-specify-second-point-for-text-angle = DIMANGULAR Especifique o segundo ponto para o ângulo do texto:
|
||||
.dimangular-specify-text-angle-or-first-point = DIMANGULAR Especifique o ângulo do texto ou o primeiro ponto:
|
||||
.dimbaseline-no-base-dimension-found-place-a-di = DIMBASELINE Nenhuma cota base encontrada. Coloque uma cota primeiro.
|
||||
.dimbaseline-specify-a-second-extension-line-or = DIMBASELINE Especifique a origem de uma segunda linha de extensão (Enter para sair):
|
||||
.dimbreak-select-dimension-to-break = DIMBREAK Selecione a cota a quebrar:
|
||||
|
|
|
|||
|
|
@ -1809,10 +1809,18 @@ annotate =
|
|||
.dimaligned-specify-first-extension-line-origin = DIMALIGNED Укажите начало первой выносной линии или нажмите Enter для выбора объекта:
|
||||
.dimaligned-specify-second-extension-line-origi = DIMALIGNED Укажите начало второй выносной линии:
|
||||
.dimaligned-specify-text-angle-degrees = DIMALIGNED Укажите угол текста (градусы):
|
||||
.dimangular-specify-angle-vertex = DIMANGULAR Укажите угол вершины:
|
||||
.dimangular-specify-dimension-arc-location = DIMANGULAR Укажите местоположение дуги размерности:
|
||||
.dimangular-specify-first-extension-line-point = DIMANGULAR Укажите первую точку расширения:
|
||||
.dimangular-specify-second-extension-line-point = DIMANGULAR Укажите вторую точку расширения:
|
||||
.dimangular-enter-dimension-text-blank-measured = DIMANGULAR Введите текст размера (пусто = измеренное значение):
|
||||
.dimangular-enter-formatted-dimension-text-blank-measured = DIMANGULAR Введите форматированный текст размера (пусто = измеренное значение):
|
||||
.dimangular-select-arc-circle-line-or-specify-angle-vertex = DIMANGULAR Выберите дугу, окружность, линию или укажите вершину угла:
|
||||
.dimangular-select-second-line = DIMANGULAR Выберите вторую линию:
|
||||
.dimangular-specify-angle-vertex = DIMANGULAR Укажите вершину угла:
|
||||
.dimangular-specify-dimension-arc-location-options = DIMANGULAR Укажите положение размерной дуги [Mtext/Текст/Угол/Квадрант]:
|
||||
.dimangular-specify-dimension-arc-location = DIMANGULAR Укажите положение размерной дуги:
|
||||
.dimangular-specify-first-extension-line-point = DIMANGULAR Укажите первую точку выносной линии:
|
||||
.dimangular-specify-quadrant = DIMANGULAR Укажите квадрант:
|
||||
.dimangular-specify-second-extension-line-point = DIMANGULAR Укажите вторую точку выносной линии:
|
||||
.dimangular-specify-second-point-for-text-angle = DIMANGULAR Укажите вторую точку угла текста:
|
||||
.dimangular-specify-text-angle-or-first-point = DIMANGULAR Укажите угол текста или первую точку:
|
||||
.dimbaseline-no-base-dimension-found-place-a-di = DIMBASELINE Базовый размер не найден. Сначала создайте размер.
|
||||
.dimbaseline-specify-a-second-extension-line-or = DIMBASELINE Укажите происхождение второй линии расширения (Введите для выхода):
|
||||
.dimbreak-select-dimension-to-break = DIMBREAK Выберите размер для разбиения:
|
||||
|
|
|
|||
|
|
@ -1816,10 +1816,18 @@ annotate =
|
|||
.dimaligned-specify-first-extension-line-origin = DIMALIGNED Birinci uzatma çizgisinin başlangıcını belirtin veya nesne seçmek için Enter'a basın:
|
||||
.dimaligned-specify-second-extension-line-origi = DIMALIGNED İkinci uzatma çizgisinin başlangıcını belirtin:
|
||||
.dimaligned-specify-text-angle-degrees = DIMALIGNED Metin açısını belirtin (derece):
|
||||
.dimangular-enter-dimension-text-blank-measured = DIMANGULAR Ölçü metnini girin (boş = ölçülen değer):
|
||||
.dimangular-enter-formatted-dimension-text-blank-measured = DIMANGULAR Biçimlendirilmiş ölçü metnini girin (boş = ölçülen değer):
|
||||
.dimangular-select-arc-circle-line-or-specify-angle-vertex = DIMANGULAR Yay, çember veya çizgi seçin ya da açı köşesi belirtin:
|
||||
.dimangular-select-second-line = DIMANGULAR İkinci çizgiyi seçin:
|
||||
.dimangular-specify-angle-vertex = DIMANGULAR Açı köşesini belirtin:
|
||||
.dimangular-specify-dimension-arc-location-options = DIMANGULAR Ölçü yayının konumunu belirtin [Mtext/Metin/Açı/Kadran]:
|
||||
.dimangular-specify-dimension-arc-location = DIMANGULAR Ölçü yayının konumunu belirtin:
|
||||
.dimangular-specify-first-extension-line-point = DIMANGULAR Birinci uzatma çizgisi noktasını belirtin:
|
||||
.dimangular-specify-quadrant = DIMANGULAR Kadranı belirtin:
|
||||
.dimangular-specify-second-extension-line-point = DIMANGULAR İkinci uzatma çizgisi noktasını belirtin:
|
||||
.dimangular-specify-second-point-for-text-angle = DIMANGULAR Metin açısının ikinci noktasını belirtin:
|
||||
.dimangular-specify-text-angle-or-first-point = DIMANGULAR Metin açısını veya ilk noktayı belirtin:
|
||||
.dimbaseline-no-base-dimension-found-place-a-di = DIMBASELINE Temel ölçü bulunamadı. Önce bir ölçü yerleştirin.
|
||||
.dimbaseline-specify-a-second-extension-line-or = DIMBASELINE İkinci uzatma çizgisinin başlangıcını belirtin (çıkmak için Enter):
|
||||
.dimbreak-select-dimension-to-break = DIMBREAK Kesilecek ölçüyü seçin:
|
||||
|
|
|
|||
|
|
@ -1793,10 +1793,18 @@ annotate =
|
|||
.dimaligned-specify-first-extension-line-origin = DIMALIGNED 指定第一条尺寸界线原点,或按 Enter 选择对象:
|
||||
.dimaligned-specify-second-extension-line-origi = DIMALIGNED 指定第二条尺寸界线原点:
|
||||
.dimaligned-specify-text-angle-degrees = DIMALIGNED 指定文字角度(度):
|
||||
.dimangular-enter-dimension-text-blank-measured = DIMANGULAR 输入标注文字(空白 = 测量值):
|
||||
.dimangular-enter-formatted-dimension-text-blank-measured = DIMANGULAR 输入带格式的标注文字(空白 = 测量值):
|
||||
.dimangular-select-arc-circle-line-or-specify-angle-vertex = DIMANGULAR 选择圆弧、圆或直线,或指定角度顶点:
|
||||
.dimangular-select-second-line = DIMANGULAR 选择第二条直线:
|
||||
.dimangular-specify-angle-vertex = DIMANGULAR 指定角度顶点:
|
||||
.dimangular-specify-dimension-arc-location-options = DIMANGULAR 指定标注圆弧位置 [Mtext/文字/角度/象限]:
|
||||
.dimangular-specify-dimension-arc-location = DIMANGULAR 指定标注圆弧位置:
|
||||
.dimangular-specify-first-extension-line-point = DIMANGULAR 指定第一条尺寸界线点:
|
||||
.dimangular-specify-quadrant = DIMANGULAR 指定象限:
|
||||
.dimangular-specify-second-extension-line-point = DIMANGULAR 指定第二条尺寸界线点:
|
||||
.dimangular-specify-second-point-for-text-angle = DIMANGULAR 指定文字角度的第二点:
|
||||
.dimangular-specify-text-angle-or-first-point = DIMANGULAR 指定文字角度或第一点:
|
||||
.dimbaseline-no-base-dimension-found-place-a-di = DIMBASELINE 未找到基准标注。请先放置标注。
|
||||
.dimbaseline-specify-a-second-extension-line-or = DIMBASELINE 指定第二条尺寸界线原点(按 Enter 退出):
|
||||
.dimbreak-select-dimension-to-break = DIMBREAK 选择要打断的标注:
|
||||
|
|
|
|||
|
|
@ -1805,10 +1805,18 @@ annotate =
|
|||
.dimaligned-specify-first-extension-line-origin = DIMALIGNED 指定第一條尺寸界線原點,或按 Enter 選取物件:
|
||||
.dimaligned-specify-second-extension-line-origi = DIMALIGNED 指定第二條尺寸界線原點:
|
||||
.dimaligned-specify-text-angle-degrees = DIMALIGNED 指定文字角度(度):
|
||||
.dimangular-enter-dimension-text-blank-measured = DIMANGULAR 輸入標註文字(空白 = 測量值):
|
||||
.dimangular-enter-formatted-dimension-text-blank-measured = DIMANGULAR 輸入帶格式的標註文字(空白 = 測量值):
|
||||
.dimangular-select-arc-circle-line-or-specify-angle-vertex = DIMANGULAR 選取圓弧、圓或直線,或指定角度頂點:
|
||||
.dimangular-select-second-line = DIMANGULAR 選取第二條直線:
|
||||
.dimangular-specify-angle-vertex = DIMANGULAR 指定角度頂點:
|
||||
.dimangular-specify-dimension-arc-location-options = DIMANGULAR 指定標註圓弧位置 [Mtext/文字/角度/象限]:
|
||||
.dimangular-specify-dimension-arc-location = DIMANGULAR 指定標註圓弧位置:
|
||||
.dimangular-specify-first-extension-line-point = DIMANGULAR 指定第一條尺寸界線點:
|
||||
.dimangular-specify-quadrant = DIMANGULAR 指定象限:
|
||||
.dimangular-specify-second-extension-line-point = DIMANGULAR 指定第二條尺寸界線點:
|
||||
.dimangular-specify-second-point-for-text-angle = DIMANGULAR 指定文字角度的第二點:
|
||||
.dimangular-specify-text-angle-or-first-point = DIMANGULAR 指定文字角度或第一點:
|
||||
.dimbaseline-no-base-dimension-found-place-a-di = DIMBASELINE 未找到基準標註。請先放置標註。
|
||||
.dimbaseline-specify-a-second-extension-line-or = DIMBASELINE 指定第二條尺寸界線原點(按 Enter 退出):
|
||||
.dimbreak-select-dimension-to-break = DIMBREAK 選擇要打斷的標註:
|
||||
|
|
|
|||
|
|
@ -581,6 +581,36 @@ impl OpenCADStudio {
|
|||
let _ = self.apply_cmd_result(r);
|
||||
return;
|
||||
}
|
||||
let accepts_points = self.tabs[i]
|
||||
.active_cmd
|
||||
.as_ref()
|
||||
.is_some_and(|command| command.entity_pick_accepts_points());
|
||||
if accepts_points {
|
||||
if let Some((coord, kind)) = super::helpers::parse_coord(token) {
|
||||
let ucs = self.tabs[i].active_ucs.clone();
|
||||
let wcs = match (
|
||||
matches!(kind, super::helpers::CoordKind::Relative),
|
||||
self.last_point,
|
||||
) {
|
||||
(true, Some(base)) => {
|
||||
base + match &ucs {
|
||||
Some(value) => super::helpers::ucs_rotate_vec(coord, value),
|
||||
None => coord,
|
||||
}
|
||||
}
|
||||
_ => match &ucs {
|
||||
Some(value) => super::helpers::ucs_to_wcs(coord, value),
|
||||
None => coord,
|
||||
},
|
||||
};
|
||||
if self.command_point_allowed(i, wcs) {
|
||||
self.last_point = Some(wcs);
|
||||
self.push_ucs_to_cmd(i);
|
||||
let _ = self.feed_command(StepInput::Point(wcs));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
if let Ok(v) = u64::from_str_radix(token.trim_start_matches("0x"), 16) {
|
||||
let handle = Handle::new(v);
|
||||
let pt = self.tabs[i]
|
||||
|
|
@ -818,7 +848,7 @@ impl OpenCADStudio {
|
|||
.infer_dimension_sources(handle);
|
||||
self.tabs[i]
|
||||
.scene
|
||||
.attach_dimension_association(handle, sources);
|
||||
.attach_dimension_association(handle, sources.to_vec());
|
||||
}
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
|
|
@ -1227,7 +1257,7 @@ impl OpenCADStudio {
|
|||
.infer_dimension_sources(handle);
|
||||
self.tabs[i]
|
||||
.scene
|
||||
.attach_dimension_association(handle, sources);
|
||||
.attach_dimension_association(handle, sources.to_vec());
|
||||
}
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
|
|
@ -1239,7 +1269,10 @@ impl OpenCADStudio {
|
|||
self.commit_undo_delta(i, pd);
|
||||
}
|
||||
}
|
||||
CmdResult::CommitDimension { mut entity, source } => {
|
||||
CmdResult::CommitDimension {
|
||||
mut entity,
|
||||
association,
|
||||
} => {
|
||||
let label = self.history_label_from_active_cmd(i, "DIMENSION");
|
||||
let association_mode = self.tabs[i]
|
||||
.scene
|
||||
|
|
@ -1293,19 +1326,37 @@ impl OpenCADStudio {
|
|||
let pending = self.begin_undo(i, label, 1, delta_safe);
|
||||
if let Some(handle) = self.commit_entity_handle(entity) {
|
||||
if association_mode == 2 {
|
||||
let sources = source.map_or_else(
|
||||
|| self.tabs[i].scene.infer_dimension_sources(handle),
|
||||
|source| [Some(source), Some(source)],
|
||||
);
|
||||
self.tabs[i]
|
||||
.scene
|
||||
.attach_dimension_association(handle, sources);
|
||||
let mut changes = vec![
|
||||
(handle, crate::scene::ChangeKind::Modified),
|
||||
];
|
||||
changes.extend(sources.into_iter().flatten().map(|source| {
|
||||
(source, crate::scene::ChangeKind::Modified)
|
||||
}));
|
||||
match association {
|
||||
crate::command::DimensionAssociationInput::Infer(source) => {
|
||||
let sources: Vec<_> = source.map_or_else(
|
||||
|| {
|
||||
self.tabs[i]
|
||||
.scene
|
||||
.infer_dimension_sources(handle)
|
||||
.into_iter()
|
||||
.collect()
|
||||
},
|
||||
|source| vec![Some(source), Some(source)],
|
||||
);
|
||||
self.tabs[i]
|
||||
.scene
|
||||
.attach_dimension_association(handle, sources.clone());
|
||||
changes.extend(sources.into_iter().flatten().map(|source| {
|
||||
(source, crate::scene::ChangeKind::Modified)
|
||||
}));
|
||||
}
|
||||
crate::command::DimensionAssociationInput::Explicit(sources) => {
|
||||
self.tabs[i]
|
||||
.scene
|
||||
.attach_dimension_association_sources(handle, sources.clone());
|
||||
changes.extend(sources.into_iter().flatten().map(|source| {
|
||||
(source.handle, crate::scene::ChangeKind::Modified)
|
||||
}));
|
||||
}
|
||||
}
|
||||
changes.sort_by_key(|(handle, _)| handle.value());
|
||||
changes.dedup_by_key(|(handle, _)| handle.value());
|
||||
self.tabs[i].scene.bump_entities(&changes);
|
||||
|
|
@ -3637,6 +3688,19 @@ impl OpenCADStudio {
|
|||
self.tabs[i].snap_result = None;
|
||||
self.open_mtext_editor(pos, handle, &initial, height);
|
||||
}
|
||||
CmdResult::SuspendForMTextInput {
|
||||
pos,
|
||||
initial,
|
||||
height,
|
||||
} => {
|
||||
self.tabs[i].suspended_cmd = self.tabs[i].active_cmd.take();
|
||||
self.tabs[i].snap_result = None;
|
||||
self.tabs[i].scene.clear_preview_wire();
|
||||
self.restore_pre_cmd_tangent();
|
||||
self.command_mtext_input = true;
|
||||
self.pending_command_editor_text = None;
|
||||
self.open_mtext_editor(pos, None, &initial, height);
|
||||
}
|
||||
CmdResult::OpenTextEditor {
|
||||
pos,
|
||||
handle,
|
||||
|
|
|
|||
|
|
@ -764,6 +764,9 @@ pub(super) struct OpenCADStudio {
|
|||
ctrl_down: bool,
|
||||
/// Open in-place MText editor (toolbar + text area + live preview), if any.
|
||||
mtext_editor: Option<mtext_editor::MTextEditorState>,
|
||||
/// Return rich text to a suspended drawing command.
|
||||
command_mtext_input: bool,
|
||||
pending_command_editor_text: Option<String>,
|
||||
/// Open in-place single-line TEXT editor (plain text-entry box), if any.
|
||||
text_inline: Option<text_inline::TextInlineState>,
|
||||
/// Cursor-anchored one-shot snap override menu (Shift+RMB): the canvas
|
||||
|
|
@ -3252,6 +3255,8 @@ impl OpenCADStudio {
|
|||
ctrl_down: false,
|
||||
cont_anchor: None,
|
||||
mtext_editor: None,
|
||||
command_mtext_input: false,
|
||||
pending_command_editor_text: None,
|
||||
text_inline: None,
|
||||
snap_override_popup: None,
|
||||
axis_lock_dir: None,
|
||||
|
|
|
|||
|
|
@ -1209,6 +1209,12 @@ impl super::OpenCADStudio {
|
|||
pub(super) fn mtext_commit(&mut self) -> bool {
|
||||
let i = self.active_tab;
|
||||
let Some(ed) = self.mtext_editor.take() else { return false };
|
||||
if self.command_mtext_input {
|
||||
self.pending_command_editor_text = Some(ed.build_mtext().value);
|
||||
self.command_mtext_input = false;
|
||||
self.refresh_properties();
|
||||
return true;
|
||||
}
|
||||
let body_empty = ed.content.text().trim().is_empty();
|
||||
let mut mt = ed.build_mtext();
|
||||
let annotative = ed.editing.is_none()
|
||||
|
|
@ -1302,6 +1308,10 @@ impl super::OpenCADStudio {
|
|||
/// then updated in place on later applies, so repeated Apply never leaves
|
||||
/// duplicate entities behind.
|
||||
pub(super) fn mtext_apply(&mut self) {
|
||||
if self.command_mtext_input {
|
||||
self.rebuild_mtext_preview();
|
||||
return;
|
||||
}
|
||||
let i = self.active_tab;
|
||||
let (mut mt, editing, body_empty) = match self.mtext_editor.as_ref() {
|
||||
Some(ed) => (
|
||||
|
|
@ -1398,6 +1408,8 @@ impl super::OpenCADStudio {
|
|||
/// Discard the editor without changing the drawing.
|
||||
pub(super) fn mtext_cancel(&mut self) {
|
||||
self.mtext_editor = None;
|
||||
self.command_mtext_input = false;
|
||||
self.pending_command_editor_text = None;
|
||||
self.reset_modal_geometry();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1144,6 +1144,31 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
|||
| GripMenuAction::MoveWithLeader
|
||||
| GripMenuAction::MoveIndependent
|
||||
) {
|
||||
let is_dimension = matches!(
|
||||
self.tabs[i].scene.document.get_entity(popup.handle),
|
||||
Some(acadrust::EntityType::Dimension(_))
|
||||
);
|
||||
if is_dimension {
|
||||
let movement = match item.action {
|
||||
GripMenuAction::MoveWithDimLine => Some("Keep dim line with text"),
|
||||
GripMenuAction::MoveWithLeader => Some("Move text, add leader"),
|
||||
GripMenuAction::MoveIndependent => Some("Move text, no leader"),
|
||||
_ => None,
|
||||
};
|
||||
if let Some(movement) = movement {
|
||||
crate::entities::dim_override::set_property(
|
||||
&mut self.tabs[i].scene.document,
|
||||
popup.handle,
|
||||
"dim_text_movement",
|
||||
movement,
|
||||
);
|
||||
self.tabs[i].dirty = true;
|
||||
self.tabs[i].scene.bump_entities(&[(
|
||||
popup.handle,
|
||||
crate::scene::ChangeKind::Modified,
|
||||
)]);
|
||||
}
|
||||
}
|
||||
// Stretch / Move = grab this grip. Engage it so the next
|
||||
// click places it (click-move-click) — same as picking the
|
||||
// grip directly in the viewport. Without this the menu just
|
||||
|
|
@ -1157,10 +1182,12 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
|||
// "Move with Leader" drags the whole multileader; the
|
||||
// others move just the picked grip.
|
||||
let (grip_id, is_translate) =
|
||||
if matches!(item.action, GripMenuAction::MoveWithLeader) {
|
||||
if matches!(item.action, GripMenuAction::MoveWithLeader)
|
||||
&& !is_dimension
|
||||
{
|
||||
(crate::entities::multileader::MOVE_ALL_GRIP, true)
|
||||
} else {
|
||||
(popup.grip_id, g.is_midpoint)
|
||||
(popup.grip_id, if is_dimension { false } else { g.is_midpoint })
|
||||
};
|
||||
self.tabs[i].active_grip = Some(GripEdit::single(
|
||||
popup.handle,
|
||||
|
|
|
|||
|
|
@ -492,6 +492,13 @@ impl OpenCADStudio {
|
|||
self.reset_modal_geometry();
|
||||
let i = self.active_tab;
|
||||
if let Some(mut cmd) = self.tabs[i].suspended_cmd.take() {
|
||||
if committed {
|
||||
if let Some(value) = self.pending_command_editor_text.take() {
|
||||
cmd.on_editor_text(value);
|
||||
}
|
||||
} else {
|
||||
self.pending_command_editor_text = None;
|
||||
}
|
||||
let res = cmd.on_editor_closed(committed);
|
||||
self.tabs[i].active_cmd = Some(cmd);
|
||||
self.apply_cmd_result(res)
|
||||
|
|
|
|||
|
|
@ -169,6 +169,38 @@ pub struct SelectionEntity {
|
|||
pub surface_area: Option<f64>,
|
||||
}
|
||||
|
||||
/// Association source with an optional sub-entity marker.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct DimensionAssociationSource {
|
||||
pub handle: Handle,
|
||||
pub marker: Option<i32>,
|
||||
pub parameter: f64,
|
||||
}
|
||||
|
||||
impl DimensionAssociationSource {
|
||||
pub const fn inferred(handle: Handle) -> Self {
|
||||
Self {
|
||||
handle,
|
||||
marker: None,
|
||||
parameter: 0.0,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn explicit(handle: Handle, marker: i32, parameter: f64) -> Self {
|
||||
Self {
|
||||
handle,
|
||||
marker: Some(marker),
|
||||
parameter,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum DimensionAssociationInput {
|
||||
Infer(Option<Handle>),
|
||||
Explicit(Vec<Option<DimensionAssociationSource>>),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum AreaPreviewSource {
|
||||
Handles(Vec<Handle>),
|
||||
|
|
@ -1212,11 +1244,10 @@ pub enum CmdResult {
|
|||
CommitEntitiesAndExit(Vec<EntityType>),
|
||||
/// Commit an acadrust entity to the document and end the command.
|
||||
CommitAndExit(EntityType),
|
||||
/// Commit a linear/aligned dimension using the drawing's association mode.
|
||||
/// Object-selection workflows may retain their source.
|
||||
/// Commit a dimension using the drawing's association mode.
|
||||
CommitDimension {
|
||||
entity: EntityType,
|
||||
source: Option<Handle>,
|
||||
association: DimensionAssociationInput,
|
||||
},
|
||||
/// Commit a Model-tab 3D solid: the acadrust entity (for selection /
|
||||
/// persistence) plus its B-rep (cached for boolean ops + shaded
|
||||
|
|
@ -1397,6 +1428,12 @@ pub enum CmdResult {
|
|||
initial: String,
|
||||
height: f64,
|
||||
},
|
||||
/// Collect rich text without creating an MText entity.
|
||||
SuspendForMTextInput {
|
||||
pos: DVec3,
|
||||
initial: String,
|
||||
height: f64,
|
||||
},
|
||||
/// Open the in-place single-line TEXT editor (a plain text-entry box, no
|
||||
/// formatting toolbar). `handle` is `Some` when editing an existing Text,
|
||||
/// `None` when creating a new one at `pos`.
|
||||
|
|
@ -1778,6 +1815,11 @@ pub trait CadCommand: Send {
|
|||
false
|
||||
}
|
||||
|
||||
/// Accept typed coordinates while object picking.
|
||||
fn entity_pick_accepts_points(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Include filled hatch / DXF SOLID regions in the entity hit-test.
|
||||
///
|
||||
/// Most entity-pick commands operate on curve geometry and intentionally
|
||||
|
|
@ -1806,6 +1848,9 @@ pub trait CadCommand: Send {
|
|||
CmdResult::Cancel
|
||||
}
|
||||
|
||||
/// Resume the command with collected rich text.
|
||||
fn on_editor_text(&mut self, _value: String) {}
|
||||
|
||||
/// Called when the user clicks and `needs_entity_pick()` is true.
|
||||
/// `handle` is the nearest wire's entity handle (Handle::NULL if nothing found).
|
||||
fn on_entity_pick(&mut self, _handle: Handle, _pt: DVec3) -> CmdResult {
|
||||
|
|
|
|||
|
|
@ -274,6 +274,8 @@ pub fn property_int_code(field: &str) -> Option<i16> {
|
|||
"dim_line_inside" => DIMSOXD,
|
||||
"dim_units" => DIMLUNIT,
|
||||
"dim_precision" => DIMDEC,
|
||||
"dim_angle_units" => DIMAUNIT,
|
||||
"dim_angle_precision" => DIMADEC,
|
||||
"dim_decimal_separator" => DIMDSEP,
|
||||
"dim_fractional_type" => DIMFRAC,
|
||||
"dim_text_view_direction" => DIMTXTDIRECTION,
|
||||
|
|
@ -330,6 +332,9 @@ fn inherited_int(doc: &CadDocument, handle: Handle, code: i16) -> i16 {
|
|||
DIMTOL => style.dimtol as i16,
|
||||
DIMLIM => style.dimlim as i16,
|
||||
DIMALT => style.dimalt as i16,
|
||||
DIMAZIN => style.dimazin,
|
||||
DIMAUNIT => style.dimaunit,
|
||||
DIMADEC => style.dimadec,
|
||||
DIMTFILL => style.dimtfill,
|
||||
DIMTALN => 0,
|
||||
_ => 0,
|
||||
|
|
@ -451,6 +456,8 @@ pub fn set_property(
|
|||
"dim_tolerance_suppress_trailing_zeros" => Some((DIMTZIN, 8)),
|
||||
"dim_alt_tolerance_suppress_leading_zeros" => Some((DIMALTTZ, 4)),
|
||||
"dim_alt_tolerance_suppress_trailing_zeros" => Some((DIMALTTZ, 8)),
|
||||
"dim_angle_suppress_leading_zeros" => Some((DIMAZIN, 1)),
|
||||
"dim_angle_suppress_trailing_zeros" => Some((DIMAZIN, 2)),
|
||||
_ => None,
|
||||
};
|
||||
if let Some((code, bit)) = bit_field {
|
||||
|
|
@ -624,6 +631,13 @@ pub fn set_property(
|
|||
"desktop" => Some(6),
|
||||
_ => trimmed.parse().ok(),
|
||||
},
|
||||
"dim_angle_units" => match trimmed.to_ascii_lowercase().as_str() {
|
||||
"decimal degrees" => Some(0),
|
||||
"degrees/minutes/seconds" => Some(1),
|
||||
"gradians" => Some(2),
|
||||
"radians" => Some(3),
|
||||
_ => trimmed.parse().ok(),
|
||||
},
|
||||
"dim_fractional_type" => match trimmed.to_ascii_lowercase().as_str() {
|
||||
"horizontal" => Some(0),
|
||||
"diagonal" => Some(1),
|
||||
|
|
|
|||
|
|
@ -124,6 +124,18 @@ fn properties(dim: &Dimension) -> Vec<PropSection> {
|
|||
],
|
||||
}];
|
||||
}
|
||||
if matches!(dim, Dimension::Angular2Ln(_) | Dimension::Angular3Pt(_)) {
|
||||
return vec![PropSection {
|
||||
title: t!("Misc").into_owned(),
|
||||
props: vec![crate::scene::model::object::Property {
|
||||
label: t!("Dimension style").into_owned(),
|
||||
field: "style_name",
|
||||
value: crate::scene::model::object::PropValue::PlainText(
|
||||
dim.base().style_name.clone(),
|
||||
),
|
||||
}],
|
||||
}];
|
||||
}
|
||||
let mut props = base_props(dim.base());
|
||||
match dim {
|
||||
Dimension::Aligned(d) => {
|
||||
|
|
@ -1064,6 +1076,12 @@ fn restore_dim_text_relative_position(
|
|||
}
|
||||
|
||||
fn dimension_line_grip_position(dim: &Dimension) -> Option<DVec3> {
|
||||
match dim {
|
||||
Dimension::Angular2Ln(d) => return Some(dv3(&d.dimension_arc)),
|
||||
Dimension::Angular3Pt(d) => return Some(dv3(&d.definition_point)),
|
||||
Dimension::Arc(d) => return Some(dv3(&d.definition_point)),
|
||||
_ => {}
|
||||
}
|
||||
let (first, second, defpt, ax, ay) = match dim {
|
||||
Dimension::Linear(d) => (
|
||||
d.first_point,
|
||||
|
|
@ -1117,6 +1135,14 @@ fn dimension_line_grip_position(dim: &Dimension) -> Option<DVec3> {
|
|||
}
|
||||
|
||||
fn above_dimension_text_position(dim: &Dimension) -> Option<DVec3> {
|
||||
if let Some((vertex, start, end, radius)) = angular_dimension_frame(dim) {
|
||||
let angle = (start + end) * 0.5;
|
||||
let direction = DVec3::new(angle.cos() as f64, angle.sin() as f64, 0.0);
|
||||
return Some(
|
||||
DVec3::new(vertex.x as f64, vertex.y as f64, vertex.z as f64)
|
||||
+ direction * (radius as f64 + 1.0),
|
||||
);
|
||||
}
|
||||
let center = dimension_line_grip_position(dim)?;
|
||||
let (ax, ay) = match dim {
|
||||
Dimension::Linear(d) => (d.rotation.cos(), d.rotation.sin()),
|
||||
|
|
@ -1179,11 +1205,12 @@ impl Grippable for Dimension {
|
|||
center_grip(2, text),
|
||||
],
|
||||
Dimension::Angular2Ln(d) => vec![
|
||||
square_grip(0, dv3(&d.angle_vertex)),
|
||||
center_grip(1, dv3(&d.first_point)),
|
||||
center_grip(2, dv3(&d.second_point)),
|
||||
square_grip(0, dv3(&d.first_point)),
|
||||
center_grip(1, dv3(&d.second_point)),
|
||||
center_grip(2, dv3(&d.angle_vertex)),
|
||||
center_grip(3, dv3(&d.definition_point)),
|
||||
center_grip(4, text),
|
||||
center_grip(4, dv3(&d.dimension_arc)),
|
||||
center_grip(5, text),
|
||||
],
|
||||
Dimension::Angular3Pt(d) => vec![
|
||||
square_grip(0, dv3(&d.angle_vertex)),
|
||||
|
|
@ -1231,7 +1258,8 @@ impl Grippable for Dimension {
|
|||
let text_grip = match self {
|
||||
Dimension::Linear(_) | Dimension::Aligned(_) => 3,
|
||||
Dimension::Radius(_) | Dimension::Diameter(_) => 2,
|
||||
Dimension::Angular2Ln(_) | Dimension::Angular3Pt(_) => 4,
|
||||
Dimension::Angular2Ln(_) => 5,
|
||||
Dimension::Angular3Pt(_) => 4,
|
||||
Dimension::Ordinate(_) => 3,
|
||||
Dimension::Arc(d) => if d.has_leader { 6 } else { 4 },
|
||||
Dimension::LargeRadial(_) => 4,
|
||||
|
|
@ -1274,10 +1302,11 @@ impl Grippable for Dimension {
|
|||
_ => {}
|
||||
},
|
||||
Dimension::Angular2Ln(d) => match grip_id {
|
||||
0 => apply_to_v3(&mut d.angle_vertex, &apply),
|
||||
1 => apply_to_v3(&mut d.first_point, &apply),
|
||||
2 => apply_to_v3(&mut d.second_point, &apply),
|
||||
0 => apply_to_v3(&mut d.first_point, &apply),
|
||||
1 => apply_to_v3(&mut d.second_point, &apply),
|
||||
2 => apply_to_v3(&mut d.angle_vertex, &apply),
|
||||
3 => apply_to_v3(&mut d.definition_point, &apply),
|
||||
4 => apply_to_v3(&mut d.dimension_arc, &apply),
|
||||
_ => {}
|
||||
},
|
||||
Dimension::Angular3Pt(d) => match grip_id {
|
||||
|
|
@ -1325,7 +1354,8 @@ impl Grippable for Dimension {
|
|||
let (dim_line_grip, text_grip) = match self {
|
||||
Dimension::Linear(_) | Dimension::Aligned(_) => (2, 3),
|
||||
Dimension::Radius(_) | Dimension::Diameter(_) => (1, 2),
|
||||
Dimension::Angular2Ln(_) | Dimension::Angular3Pt(_) => (3, 4),
|
||||
Dimension::Angular2Ln(_) => (4, 5),
|
||||
Dimension::Angular3Pt(_) => (3, 4),
|
||||
Dimension::Ordinate(_) => (0, 3),
|
||||
Dimension::Arc(d) => (3, if d.has_leader { 6 } else { 4 }),
|
||||
Dimension::LargeRadial(_) => (3, 4),
|
||||
|
|
@ -1393,7 +1423,8 @@ impl Grippable for Dimension {
|
|||
let (_dim_line_grip, text_grip) = match self {
|
||||
Dimension::Linear(_) | Dimension::Aligned(_) => (2, 3),
|
||||
Dimension::Radius(_) | Dimension::Diameter(_) => (1, 2),
|
||||
Dimension::Angular2Ln(_) | Dimension::Angular3Pt(_) => (3, 4),
|
||||
Dimension::Angular2Ln(_) => (4, 5),
|
||||
Dimension::Angular3Pt(_) => (3, 4),
|
||||
Dimension::Ordinate(_) => (0, 3),
|
||||
Dimension::Arc(d) => (3, if d.has_leader { 6 } else { 4 }),
|
||||
Dimension::LargeRadial(_) => (3, 4),
|
||||
|
|
@ -1440,7 +1471,8 @@ impl Grippable for Dimension {
|
|||
let text_grip = match self {
|
||||
Dimension::Linear(_) | Dimension::Aligned(_) => 3,
|
||||
Dimension::Radius(_) | Dimension::Diameter(_) => 2,
|
||||
Dimension::Angular2Ln(_) | Dimension::Angular3Pt(_) => 4,
|
||||
Dimension::Angular2Ln(_) => 5,
|
||||
Dimension::Angular3Pt(_) => 4,
|
||||
Dimension::Ordinate(_) => 3,
|
||||
Dimension::Arc(d) => if d.has_leader { 6 } else { 4 },
|
||||
Dimension::LargeRadial(_) => 4,
|
||||
|
|
@ -1682,7 +1714,7 @@ pub fn style_sections(
|
|||
_ => choice_value("None", &["None", "Background", "Color"]),
|
||||
};
|
||||
|
||||
vec![
|
||||
let mut sections = vec![
|
||||
PropSection {
|
||||
title: t!("Lines & Arrows").into_owned(),
|
||||
props: vec![
|
||||
|
|
@ -2009,19 +2041,19 @@ pub fn style_sections(
|
|||
text(
|
||||
t!("Decimal separator").as_ref(),
|
||||
"dim_decimal_separator",
|
||||
decimal_separator,
|
||||
decimal_separator.clone(),
|
||||
true,
|
||||
),
|
||||
text(
|
||||
t!("Dim prefix").as_ref(),
|
||||
t!("Prefix").as_ref(),
|
||||
"dim_prefix",
|
||||
dim_prefix,
|
||||
dim_prefix.clone(),
|
||||
true,
|
||||
),
|
||||
text(
|
||||
t!("Dim suffix").as_ref(),
|
||||
t!("Suffix").as_ref(),
|
||||
"dim_suffix",
|
||||
dim_suffix,
|
||||
dim_suffix.clone(),
|
||||
true,
|
||||
),
|
||||
text(
|
||||
|
|
@ -2312,7 +2344,81 @@ pub fn style_sections(
|
|||
),
|
||||
],
|
||||
},
|
||||
]
|
||||
];
|
||||
|
||||
if matches!(dimension, Dimension::Angular2Ln(_) | Dimension::Angular3Pt(_)) {
|
||||
if let Some(text_section) = sections
|
||||
.iter_mut()
|
||||
.find(|section| section.title == t!("Text").as_ref())
|
||||
{
|
||||
text_section
|
||||
.props
|
||||
.retain(|property| property.field != "dim_fractional_type");
|
||||
}
|
||||
|
||||
let angle_zero_suppression = int(ov::DIMAZIN, s.dimazin);
|
||||
let angle_unit = int(ov::DIMAUNIT, s.dimaunit);
|
||||
if let Some(primary_units) = sections
|
||||
.iter_mut()
|
||||
.find(|section| section.title == t!("Primary Units").as_ref())
|
||||
{
|
||||
primary_units.props = vec![
|
||||
text(
|
||||
t!("Decimal separator").as_ref(),
|
||||
"dim_decimal_separator",
|
||||
decimal_separator,
|
||||
true,
|
||||
),
|
||||
text(t!("Prefix").as_ref(), "dim_prefix", dim_prefix, true),
|
||||
text(t!("Suffix").as_ref(), "dim_suffix", dim_suffix, true),
|
||||
choice(
|
||||
t!("Angle format").as_ref(),
|
||||
"dim_angle_units",
|
||||
angular_unit_label(angle_unit),
|
||||
&[
|
||||
"Decimal degrees",
|
||||
"Degrees/minutes/seconds",
|
||||
"Gradians",
|
||||
"Radians",
|
||||
],
|
||||
true,
|
||||
),
|
||||
choice(
|
||||
t!("Suppress leading zeros").as_ref(),
|
||||
"dim_angle_suppress_leading_zeros",
|
||||
yes(angle_zero_suppression & 1 != 0),
|
||||
&["Yes", "No"],
|
||||
true,
|
||||
),
|
||||
choice(
|
||||
t!("Suppress trailing zeros").as_ref(),
|
||||
"dim_angle_suppress_trailing_zeros",
|
||||
yes(angle_zero_suppression & 2 != 0),
|
||||
&["Yes", "No"],
|
||||
true,
|
||||
),
|
||||
property(
|
||||
t!("Precision").as_ref(),
|
||||
"dim_angle_precision",
|
||||
PropValue::Choice {
|
||||
selected: int(ov::DIMADEC, s.dimadec).to_string(),
|
||||
options: (-1..=8).map(|value| value.to_string()).collect(),
|
||||
},
|
||||
),
|
||||
];
|
||||
}
|
||||
sections.retain(|section| section.title != t!("Alternate Units").as_ref());
|
||||
if let Some(tolerances) = sections
|
||||
.iter_mut()
|
||||
.find(|section| section.title == t!("Tolerances").as_ref())
|
||||
{
|
||||
tolerances
|
||||
.props
|
||||
.retain(|property| !property.field.starts_with("dim_alt_tolerance_"));
|
||||
}
|
||||
}
|
||||
|
||||
sections
|
||||
}
|
||||
|
||||
fn property(label: &str, field: &'static str, value: PropValue) -> Property {
|
||||
|
|
@ -2396,6 +2502,15 @@ fn alternate_unit_label(value: i16) -> &'static str {
|
|||
}
|
||||
}
|
||||
|
||||
fn angular_unit_label(value: i16) -> &'static str {
|
||||
match value {
|
||||
1 => "Degrees/minutes/seconds",
|
||||
2 => "Gradians",
|
||||
3 => "Radians",
|
||||
_ => "Decimal degrees",
|
||||
}
|
||||
}
|
||||
|
||||
fn tolerance_vertical_label(value: i16) -> &'static str {
|
||||
match value {
|
||||
0 => "Bottom",
|
||||
|
|
@ -2458,7 +2573,7 @@ use acadrust::{CadDocument, EntityType, Handle};
|
|||
|
||||
use crate::scene::convert::tess_util::aci_to_rgba;
|
||||
use crate::scene::convert::tessellate::{
|
||||
add_polyline, add_segment, append_arrow, arrow_from_block_with_deferred_hatch,
|
||||
add_segment, append_arrow, arrow_from_block_with_deferred_hatch,
|
||||
normalized_or, ArrowKind, DimGeom,
|
||||
};
|
||||
use crate::scene::model::wire_model::{SnapHint, WireModel};
|
||||
|
|
@ -3410,6 +3525,8 @@ fn dimtmove_leader_endpoints(dim: &Dimension) -> Option<(Vec3, Vec3)> {
|
|||
}
|
||||
Dimension::Radius(d) => lv(d.definition_point),
|
||||
Dimension::Diameter(d) => (lv(d.angle_vertex) + lv(d.definition_point)) * 0.5,
|
||||
Dimension::Angular2Ln(d) => lv(d.dimension_arc),
|
||||
Dimension::Angular3Pt(d) => lv(d.definition_point),
|
||||
_ => return None,
|
||||
};
|
||||
Some((anchor, lv(txt)))
|
||||
|
|
@ -3612,12 +3729,14 @@ fn dimension_geometry(
|
|||
Some((vertex, start, end)) => append_angular_dimension(
|
||||
&mut g,
|
||||
vertex,
|
||||
vertex + Vec3::new(start.cos(), start.sin(), 0.0) * vertex.distance(arc_point),
|
||||
vertex + Vec3::new(end.cos(), end.sin(), 0.0) * vertex.distance(arc_point),
|
||||
vertex,
|
||||
vertex,
|
||||
arc_point,
|
||||
arrow1,
|
||||
arrow2,
|
||||
Some((start, end)),
|
||||
params,
|
||||
suppress,
|
||||
),
|
||||
// Parallel lines have no vertex and so no angle to draw; the
|
||||
// extension lines alone say where the dimension was.
|
||||
|
|
@ -3628,15 +3747,29 @@ fn dimension_geometry(
|
|||
}
|
||||
}
|
||||
Dimension::Angular3Pt(d) => {
|
||||
let vertex = lv(d.angle_vertex);
|
||||
let first = lv(d.first_point);
|
||||
let second = lv(d.second_point);
|
||||
let arc_point = lv(d.definition_point);
|
||||
let explicit_sweep = two_line_angle_frame(
|
||||
vertex,
|
||||
first,
|
||||
vertex,
|
||||
second,
|
||||
arc_point,
|
||||
)
|
||||
.map(|(_, start, end)| (start, end));
|
||||
append_angular_dimension(
|
||||
&mut g,
|
||||
lv(d.angle_vertex),
|
||||
lv(d.first_point),
|
||||
lv(d.second_point),
|
||||
lv(d.definition_point),
|
||||
vertex,
|
||||
first,
|
||||
second,
|
||||
arc_point,
|
||||
arrow1,
|
||||
arrow2,
|
||||
None,
|
||||
explicit_sweep,
|
||||
params,
|
||||
suppress,
|
||||
);
|
||||
}
|
||||
Dimension::Ordinate(d) => {
|
||||
|
|
@ -3664,6 +3797,8 @@ fn dimension_geometry(
|
|||
d.arc_start_parameter as f32,
|
||||
d.arc_end_parameter as f32,
|
||||
)),
|
||||
params,
|
||||
suppress,
|
||||
);
|
||||
if d.has_leader {
|
||||
add_segment(
|
||||
|
|
@ -3924,14 +4059,13 @@ fn two_line_angle_frame(
|
|||
arc_point: Vec3,
|
||||
) -> Option<(Vec3, f32, f32)> {
|
||||
let (u, v) = (a2 - a1, b2 - b1);
|
||||
let denominator = u.x * v.y - u.y * v.x;
|
||||
// Near-parallel: the crossing runs away to infinity and the sweep with it.
|
||||
if denominator.abs() <= 1e-9 * u.length().max(v.length()).max(1.0) {
|
||||
return None;
|
||||
}
|
||||
let w = b1 - a1;
|
||||
let t = (w.x * v.y - w.y * v.x) / denominator;
|
||||
let vertex = a1 + u * t;
|
||||
let (t, _) = cadkernel::geom2d::line_line(
|
||||
[a1.x as f64, a1.y as f64],
|
||||
[u.x as f64, u.y as f64],
|
||||
[b1.x as f64, b1.y as f64],
|
||||
[v.x as f64, v.y as f64],
|
||||
)?;
|
||||
let vertex = a1 + u * t as f32;
|
||||
|
||||
// Two lines cross at four angles; the arc point picks one. Each line
|
||||
// contributes its direction and its reverse, so try the four pairs and keep
|
||||
|
|
@ -3965,6 +4099,38 @@ fn two_line_angle_frame(
|
|||
Some((vertex, start, end))
|
||||
}
|
||||
|
||||
fn angular_dimension_frame(dim: &Dimension) -> Option<(Vec3, f32, f32, f32)> {
|
||||
let (vertex, start, end, arc_point) = match dim {
|
||||
Dimension::Angular2Ln(value) => {
|
||||
let first_start = vec3_local(value.first_point);
|
||||
let first_end = vec3_local(value.second_point);
|
||||
let second_start = vec3_local(value.angle_vertex);
|
||||
let second_end = vec3_local(value.definition_point);
|
||||
let arc_point = vec3_local(value.dimension_arc);
|
||||
let (vertex, start, end) = two_line_angle_frame(
|
||||
first_start,
|
||||
first_end,
|
||||
second_start,
|
||||
second_end,
|
||||
arc_point,
|
||||
)?;
|
||||
(vertex, start, end, arc_point)
|
||||
}
|
||||
Dimension::Angular3Pt(value) => {
|
||||
let vertex = vec3_local(value.angle_vertex);
|
||||
let first = vec3_local(value.first_point);
|
||||
let second = vec3_local(value.second_point);
|
||||
let arc_point = vec3_local(value.definition_point);
|
||||
let (vertex, start, end) =
|
||||
two_line_angle_frame(vertex, first, vertex, second, arc_point)?;
|
||||
(vertex, start, end, arc_point)
|
||||
}
|
||||
_ => return None,
|
||||
};
|
||||
let radius = vertex.distance(arc_point);
|
||||
(radius > 1.0e-6).then_some((vertex, start, end, radius))
|
||||
}
|
||||
|
||||
fn append_angular_dimension(
|
||||
g: &mut DimGeom,
|
||||
vertex: Vec3,
|
||||
|
|
@ -3974,6 +4140,8 @@ fn append_angular_dimension(
|
|||
arrow1: &ArrowKind,
|
||||
arrow2: &ArrowKind,
|
||||
explicit_sweep: Option<(f32, f32)>,
|
||||
params: DimLineParams,
|
||||
suppress: SuppressFlags,
|
||||
) {
|
||||
let radius = vertex.distance(arc_point);
|
||||
if radius <= 1e-6 {
|
||||
|
|
@ -3988,8 +4156,30 @@ fn append_angular_dimension(
|
|||
let (start, mut end) = explicit_sweep.unwrap_or((measured_start, measured_end));
|
||||
let dir1 = Vec3::new(start.cos(), start.sin(), 0.0);
|
||||
let dir2 = Vec3::new(end.cos(), end.sin(), 0.0);
|
||||
add_segment(&mut g.ext_lines, first, vertex + dir1 * radius);
|
||||
add_segment(&mut g.ext_lines, second, vertex + dir2 * radius);
|
||||
let arc_start = vertex + dir1 * radius;
|
||||
let arc_end = vertex + dir2 * radius;
|
||||
let extension = |origin: Vec3, endpoint: Vec3, direction: Vec3| {
|
||||
if params.dimfxlon {
|
||||
(
|
||||
endpoint - direction * params.dimfxl.max(0.0),
|
||||
endpoint + direction * params.dimexe,
|
||||
)
|
||||
} else {
|
||||
let toward_arc = normalized_or(endpoint - origin, direction);
|
||||
(
|
||||
origin + toward_arc * params.dimexo,
|
||||
endpoint + toward_arc * params.dimexe,
|
||||
)
|
||||
}
|
||||
};
|
||||
let (ext1_start, ext1_end) = extension(first, arc_start, dir1);
|
||||
let (ext2_start, ext2_end) = extension(second, arc_end, dir2);
|
||||
if !suppress.ext1 {
|
||||
add_segment(&mut g.ext_lines, ext1_start, ext1_end);
|
||||
}
|
||||
if !suppress.ext2 {
|
||||
add_segment(&mut g.ext_lines, ext2_start, ext2_end);
|
||||
}
|
||||
|
||||
let mut delta = end - start;
|
||||
// Wrap a negative sweep forwards, but leave a zero one alone: two rays that
|
||||
|
|
@ -4006,32 +4196,158 @@ fn append_angular_dimension(
|
|||
delta = end - start;
|
||||
}
|
||||
|
||||
let steps = 32;
|
||||
let mut arc_pts = Vec::with_capacity((steps + 1) as usize);
|
||||
for i in 0..=steps {
|
||||
let t = i as f32 / steps as f32;
|
||||
let a = start + delta * t;
|
||||
arc_pts.push(vertex + Vec3::new(a.cos() * radius, a.sin() * radius, 0.0));
|
||||
let arc_length = radius * delta.abs();
|
||||
let arrows_outside = if params.ticks || params.arrow_len <= 1.0e-6 {
|
||||
false
|
||||
} else if arc_length < params.arrow_len * 2.0 {
|
||||
true
|
||||
} else if arc_length < params.text_width + params.arrow_len * 2.0 {
|
||||
match params.dimatfit {
|
||||
0 | 1 => true,
|
||||
2 => false,
|
||||
_ => params.text_width <= arc_length,
|
||||
}
|
||||
} else {
|
||||
false
|
||||
};
|
||||
let draw_inside_line = !arrows_outside || params.dimtofl;
|
||||
let arc_extension = if params.ticks { params.dimdle / radius } else { 0.0 };
|
||||
let direction = delta.signum();
|
||||
let draw_start = start - direction * arc_extension;
|
||||
let draw_delta = delta + direction * arc_extension * 2.0;
|
||||
let arc_pts = sample_angular_arc(vertex, radius, draw_start, draw_delta);
|
||||
let steps = arc_pts.len().saturating_sub(1);
|
||||
if draw_inside_line {
|
||||
for index in 0..steps {
|
||||
let t = (index as f32 + 0.5) / steps as f32;
|
||||
if (t < 0.5 && suppress.dim1) || (t >= 0.5 && suppress.dim2) {
|
||||
continue;
|
||||
}
|
||||
let a = arc_pts[index];
|
||||
let b = arc_pts[index + 1];
|
||||
let hidden_by_text = params.text_break.is_some_and(|(center, half_width, half_height)| {
|
||||
let angle = draw_start + draw_delta * t;
|
||||
let radial = Vec3::new(angle.cos(), angle.sin(), 0.0);
|
||||
let tangent = Vec3::new(-angle.sin(), angle.cos(), 0.0);
|
||||
let offset = center - (a + b) * 0.5;
|
||||
offset.dot(tangent).abs() <= half_width
|
||||
&& offset.dot(radial).abs() <= half_height
|
||||
});
|
||||
if !hidden_by_text {
|
||||
add_segment(&mut g.dim_lines, a, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
add_polyline(&mut g.dim_lines, &arc_pts);
|
||||
|
||||
if arc_pts.len() >= 2 {
|
||||
if arrows_outside && !params.dimsoxd {
|
||||
let stub_angle = (params.arrow_len * 2.0 / radius).min(std::f32::consts::FRAC_PI_2);
|
||||
if !suppress.dim1 {
|
||||
append_sampled_arc(
|
||||
&mut g.dim_lines,
|
||||
vertex,
|
||||
radius,
|
||||
start - direction * stub_angle,
|
||||
start,
|
||||
);
|
||||
}
|
||||
if !suppress.dim2 {
|
||||
append_sampled_arc(
|
||||
&mut g.dim_lines,
|
||||
vertex,
|
||||
radius,
|
||||
end,
|
||||
end + direction * stub_angle,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some((text_center, half_width, _)) = params.text_break {
|
||||
let text_angle = (text_center.y - vertex.y).atan2(text_center.x - vertex.x);
|
||||
let into = (text_angle - start).rem_euclid(std::f32::consts::TAU);
|
||||
if into > delta.abs() + 1.0e-6 {
|
||||
let back_to_start = (start - text_angle).rem_euclid(std::f32::consts::TAU);
|
||||
let forward_from_end = (text_angle - end).rem_euclid(std::f32::consts::TAU);
|
||||
let text_gap = (half_width / radius).min(std::f32::consts::FRAC_PI_2);
|
||||
if back_to_start <= forward_from_end && !suppress.dim1 {
|
||||
append_sampled_arc(
|
||||
&mut g.dim_lines,
|
||||
vertex,
|
||||
radius,
|
||||
text_angle + text_gap,
|
||||
start,
|
||||
);
|
||||
} else if !suppress.dim2 {
|
||||
append_sampled_arc(
|
||||
&mut g.dim_lines,
|
||||
vertex,
|
||||
radius,
|
||||
end,
|
||||
text_angle - text_gap,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let start_tangent = Vec3::new(-start.sin(), start.cos(), 0.0) * direction;
|
||||
let end_tangent = Vec3::new(-end.sin(), end.cos(), 0.0) * direction;
|
||||
let draw_arrows = !arrows_outside || !params.dimsoxd;
|
||||
if draw_arrows && !suppress.dim1 {
|
||||
append_arrow(
|
||||
g,
|
||||
arc_pts[0],
|
||||
normalized_or(arc_pts[1] - arc_pts[0], Vec3::X),
|
||||
arc_start,
|
||||
if arrows_outside { -start_tangent } else { start_tangent },
|
||||
arrow1,
|
||||
);
|
||||
let n = arc_pts.len();
|
||||
}
|
||||
if draw_arrows && !suppress.dim2 {
|
||||
append_arrow(
|
||||
g,
|
||||
arc_pts[n - 1],
|
||||
normalized_or(arc_pts[n - 2] - arc_pts[n - 1], Vec3::X),
|
||||
arc_end,
|
||||
if arrows_outside { end_tangent } else { -end_tangent },
|
||||
arrow2,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn append_sampled_arc(
|
||||
lines: &mut Vec<[f32; 3]>,
|
||||
vertex: Vec3,
|
||||
radius: f32,
|
||||
start: f32,
|
||||
end: f32,
|
||||
) {
|
||||
for pair in sample_angular_arc(vertex, radius, start, end - start).windows(2) {
|
||||
add_segment(lines, pair[0], pair[1]);
|
||||
}
|
||||
}
|
||||
|
||||
fn sample_angular_arc(vertex: Vec3, radius: f32, start: f32, sweep: f32) -> Vec<Vec3> {
|
||||
if sweep.abs() <= 1.0e-6 {
|
||||
return vec![vertex + Vec3::new(start.cos() * radius, start.sin() * radius, 0.0)];
|
||||
}
|
||||
let end = start + sweep;
|
||||
let (from, to, reverse) = if sweep >= 0.0 {
|
||||
(start, end, false)
|
||||
} else {
|
||||
(end, start, true)
|
||||
};
|
||||
let mut points: Vec<_> = cadkernel::geom2d::tessellate::arc(
|
||||
[vertex.x as f64, vertex.y as f64],
|
||||
radius as f64,
|
||||
from as f64,
|
||||
to as f64,
|
||||
vertex.z as f64,
|
||||
cadkernel::geom2d::tessellate::DEFAULT_SEGMENTS_PER_RADIAN,
|
||||
)
|
||||
.into_iter()
|
||||
.map(|point| Vec3::new(point[0] as f32, point[1] as f32, point[2] as f32))
|
||||
.collect();
|
||||
if reverse {
|
||||
points.reverse();
|
||||
}
|
||||
points
|
||||
}
|
||||
|
||||
fn dimension_snap_pts(dim: &Dimension) -> Vec<(glam::DVec3, SnapHint)> {
|
||||
let lv = |v: acadrust::types::Vector3| glam::DVec3::new(v.x, v.y, v.z);
|
||||
let node = |v: acadrust::types::Vector3| (lv(v), SnapHint::Node);
|
||||
|
|
@ -4049,10 +4365,11 @@ fn dimension_snap_pts(dim: &Dimension) -> Vec<(glam::DVec3, SnapHint)> {
|
|||
Dimension::Radius(d) => vec![node(d.angle_vertex), node(d.definition_point)],
|
||||
Dimension::Diameter(d) => vec![node(d.angle_vertex), node(d.definition_point)],
|
||||
Dimension::Angular2Ln(d) => vec![
|
||||
node(d.angle_vertex),
|
||||
node(d.first_point),
|
||||
node(d.second_point),
|
||||
node(d.angle_vertex),
|
||||
node(d.definition_point),
|
||||
node(d.dimension_arc),
|
||||
],
|
||||
Dimension::Angular3Pt(d) => vec![
|
||||
node(d.angle_vertex),
|
||||
|
|
@ -4288,6 +4605,32 @@ fn dimension_text_is_outside(dim: &Dimension, style: Option<&DimStyle>) -> bool
|
|||
let Some(style) = style else {
|
||||
return false;
|
||||
};
|
||||
if let Some((vertex, start, end, radius)) = angular_dimension_frame(dim) {
|
||||
if dim.base().text_user_positioned {
|
||||
let text = vec3_local(dim.base().text_middle_point);
|
||||
let angle = (text.y - vertex.y).atan2(text.x - vertex.x);
|
||||
return (angle - start).rem_euclid(std::f32::consts::TAU)
|
||||
> end - start + 1.0e-6;
|
||||
}
|
||||
if style.dimtix {
|
||||
return false;
|
||||
}
|
||||
let scale = if style.dimscale > 1e-9 { style.dimscale } else { 1.0 };
|
||||
let height = style.dimtxt * scale;
|
||||
let gap = style.dimgap.abs() * scale;
|
||||
let text_width = dimension_text_value(dim, Some(style))
|
||||
.map(|value| value.chars().count() as f64 * height * 0.6 + gap * 2.0)
|
||||
.unwrap_or(0.0);
|
||||
let arrow = style.dimasz * scale;
|
||||
let span = radius as f64 * (end - start).abs() as f64;
|
||||
let insufficient = text_width + arrow * 2.0 > span;
|
||||
return insufficient
|
||||
&& match style.dimatfit {
|
||||
0 | 2 => true,
|
||||
1 | 3 => text_width > span,
|
||||
_ => text_width > span,
|
||||
};
|
||||
}
|
||||
let (first, second, axis) = match dim {
|
||||
Dimension::Linear(d) => (
|
||||
d.first_point,
|
||||
|
|
@ -4338,6 +4681,11 @@ fn dimension_text_natural_rotation(dim: &Dimension) -> f64 {
|
|||
let dy = d.second_point.y - d.first_point.y;
|
||||
dy.atan2(dx)
|
||||
}
|
||||
Dimension::Angular2Ln(_) | Dimension::Angular3Pt(_) => angular_dimension_frame(dim)
|
||||
.map(|(_, start, end, _)| {
|
||||
((start + end) * 0.5 + std::f32::consts::FRAC_PI_2) as f64
|
||||
})
|
||||
.unwrap_or(0.0),
|
||||
_ => 0.0,
|
||||
};
|
||||
// Clamp to (-π/2, π/2] so text never appears upside-down.
|
||||
|
|
@ -4822,54 +5170,62 @@ fn reduce_fraction(mut n: u64, mut d: u64) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
/// Format an angular measurement (input in degrees as Dimension::measurement
|
||||
/// returns for angular variants) honouring DIMAUNIT, DIMADEC, DIMAZIN.
|
||||
/// Format an angular measurement in degrees using the angular style settings.
|
||||
fn format_angular_value(measurement_deg: f64, style: Option<&DimStyle>) -> String {
|
||||
let (aunit, adec, azin) = style
|
||||
.map(|s| (s.dimaunit, s.dimadec, s.dimazin))
|
||||
.unwrap_or((0, 2, 0));
|
||||
let adec = adec.max(0) as usize;
|
||||
let (aunit, adec, azin, decimal_separator) = style
|
||||
.map(|s| {
|
||||
let precision = if s.dimadec < 0 { s.dimdec } else { s.dimadec };
|
||||
(s.dimaunit, precision, s.dimazin, s.dimdsep)
|
||||
})
|
||||
.unwrap_or((0, 2, 0, b'.' as i16));
|
||||
let adec = adec.clamp(0, 8) as usize;
|
||||
|
||||
match aunit {
|
||||
// 1 = Degrees / Minutes / Seconds
|
||||
1 => format_dms(measurement_deg, adec, azin),
|
||||
1 => format_dms(measurement_deg, adec, azin, decimal_separator),
|
||||
// 2 = Gradians
|
||||
2 => {
|
||||
let g = measurement_deg / 0.9;
|
||||
let raw = format!("{:.*}", adec, g);
|
||||
format!("{}g", apply_angular_zero_suppression(&raw, azin))
|
||||
format!(
|
||||
"{}g",
|
||||
swap_decimal_sep(&apply_angular_zero_suppression(&raw, azin), decimal_separator)
|
||||
)
|
||||
}
|
||||
// 3 = Radians
|
||||
3 => {
|
||||
let r = measurement_deg.to_radians();
|
||||
let raw = format!("{:.*}", adec, r);
|
||||
format!("{}r", apply_angular_zero_suppression(&raw, azin))
|
||||
format!(
|
||||
"{}r",
|
||||
swap_decimal_sep(&apply_angular_zero_suppression(&raw, azin), decimal_separator)
|
||||
)
|
||||
}
|
||||
// 0 or unknown = Decimal Degrees
|
||||
_ => {
|
||||
let raw = format!("{:.*}", adec, measurement_deg);
|
||||
format!("{}°", apply_angular_zero_suppression(&raw, azin))
|
||||
format!(
|
||||
"{}°",
|
||||
swap_decimal_sep(&apply_angular_zero_suppression(&raw, azin), decimal_separator)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn format_dms(deg: f64, sec_dec: usize, azin: i16) -> String {
|
||||
fn format_dms(deg: f64, sec_dec: usize, azin: i16, decimal_separator: i16) -> String {
|
||||
let sign = if deg < 0.0 { "-" } else { "" };
|
||||
let abs = deg.abs();
|
||||
let d = abs.floor();
|
||||
let m_full = (abs - d) * 60.0;
|
||||
let m = m_full.floor();
|
||||
let s = (m_full - m) * 60.0;
|
||||
let scale = 10_u64.pow(sec_dec.min(8) as u32) as f64;
|
||||
let total_ticks = (deg.abs() * 3600.0 * scale).round();
|
||||
let d = (total_ticks / (3600.0 * scale)).floor();
|
||||
let remaining = total_ticks - d * 3600.0 * scale;
|
||||
let m = (remaining / (60.0 * scale)).floor();
|
||||
let s = (remaining - m * 60.0 * scale) / scale;
|
||||
let s_str = format!("{:.*}", sec_dec, s);
|
||||
let mut out = format!("{}{:.0}°{:.0}'{}\"", sign, d, m, s_str);
|
||||
if azin & 4 != 0 {
|
||||
// suppress 0° / 0' parts
|
||||
if d == 0.0 {
|
||||
out = out.trim_start_matches('0').to_string();
|
||||
out = out.replacen("°", "", 1);
|
||||
}
|
||||
}
|
||||
out
|
||||
let s_str = swap_decimal_sep(
|
||||
&apply_angular_zero_suppression(&s_str, azin),
|
||||
decimal_separator,
|
||||
);
|
||||
format!("{}{:.0}°{:.0}'{}\"", sign, d, m, s_str)
|
||||
}
|
||||
|
||||
/// Apply DIMZIN bit flags to a formatted linear value.
|
||||
|
|
@ -5119,6 +5475,32 @@ fn dimension_text_pos_f64(
|
|||
dimtad,
|
||||
)
|
||||
}
|
||||
Dimension::Angular2Ln(_) | Dimension::Angular3Pt(_) => {
|
||||
let Some((vertex, start, end, radius)) = angular_dimension_frame(dim) else {
|
||||
return base.text_middle_point;
|
||||
};
|
||||
let span = radius as f64 * (end - start).abs() as f64;
|
||||
let insufficient = text_w + arrow * 2.0 > span;
|
||||
let move_outside = !dimtix
|
||||
&& insufficient
|
||||
&& match dimatfit {
|
||||
0 | 2 => true,
|
||||
1 | 3 => text_w > span,
|
||||
_ => text_w > span,
|
||||
};
|
||||
let angle = if move_outside {
|
||||
end as f64 + (text_w * 0.5 + dimgap + arrow) / (radius as f64).max(1.0e-12)
|
||||
} else {
|
||||
((start + end) * 0.5) as f64
|
||||
};
|
||||
let radial_offset = if dimtad == 4 { -perp_off } else { perp_off };
|
||||
let text_radius = (radius as f64 + radial_offset).max(0.0);
|
||||
Vector3::new(
|
||||
vertex.x as f64 + angle.cos() * text_radius,
|
||||
vertex.y as f64 + angle.sin() * text_radius,
|
||||
vertex.z as f64,
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
// Non-linear (radius / diameter / angular / ordinate): lift the
|
||||
// natural mid point straight up by the style offset. A user-dragged
|
||||
|
|
|
|||
|
|
@ -737,10 +737,18 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static
|
|||
"DIMALIGNED Specify second extension line origin:" => Some(("annotate", "dimaligned-specify-second-extension-line-origi")),
|
||||
"DIMALIGNED Specify second extension line origin [Text/Angle]:" => Some(("annotate", "dimaligned-specify-second-extension-line-origi")),
|
||||
"DIMALIGNED Specify text angle (degrees):" => Some(("annotate", "dimaligned-specify-text-angle-degrees")),
|
||||
"DIMANGULAR Enter dimension text (blank = measured value):" => Some(("annotate", "dimangular-enter-dimension-text-blank-measured")),
|
||||
"DIMANGULAR Enter formatted dimension text (blank = measured value):" => Some(("annotate", "dimangular-enter-formatted-dimension-text-blank-measured")),
|
||||
"DIMANGULAR Select arc, circle, line, or specify an angle vertex:" => Some(("annotate", "dimangular-select-arc-circle-line-or-specify-angle-vertex")),
|
||||
"DIMANGULAR Select second line:" => Some(("annotate", "dimangular-select-second-line")),
|
||||
"DIMANGULAR Specify angle vertex:" => Some(("annotate", "dimangular-specify-angle-vertex")),
|
||||
"DIMANGULAR Specify dimension arc location [Mtext/Text/Angle/Quadrant]:" => Some(("annotate", "dimangular-specify-dimension-arc-location-options")),
|
||||
"DIMANGULAR Specify dimension arc location:" => Some(("annotate", "dimangular-specify-dimension-arc-location")),
|
||||
"DIMANGULAR Specify first extension line point:" => Some(("annotate", "dimangular-specify-first-extension-line-point")),
|
||||
"DIMANGULAR Specify quadrant:" => Some(("annotate", "dimangular-specify-quadrant")),
|
||||
"DIMANGULAR Specify second extension line point:" => Some(("annotate", "dimangular-specify-second-extension-line-point")),
|
||||
"DIMANGULAR Specify second point for text angle:" => Some(("annotate", "dimangular-specify-second-point-for-text-angle")),
|
||||
"DIMANGULAR Specify text angle or first point:" => Some(("annotate", "dimangular-specify-text-angle-or-first-point")),
|
||||
"DIMBASELINE No base dimension found. Place a dimension first." => Some(("annotate", "dimbaseline-no-base-dimension-found-place-a-di")),
|
||||
"DIMBASELINE Specify a second extension line origin (Enter to exit):" => Some(("annotate", "dimbaseline-specify-a-second-extension-line-or")),
|
||||
"DIMBREAK Select dimension to break:" => Some(("annotate", "dimbreak-select-dimension-to-break")),
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use acadrust::types::{Handle, Vector3};
|
|||
use acadrust::EntityType;
|
||||
use glam::DVec3;
|
||||
|
||||
use crate::command::{CadCommand, CmdResult, WorkingPlane};
|
||||
use crate::command::{CadCommand, CmdResult, DimensionAssociationInput, WorkingPlane};
|
||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
use crate::t;
|
||||
|
|
@ -134,7 +134,7 @@ impl CadCommand for AlignedDimensionCommand {
|
|||
}
|
||||
CmdResult::CommitDimension {
|
||||
entity: self.plane.place_entity(EntityType::Dimension(Dimension::Aligned(dim))),
|
||||
source: self.source_handle,
|
||||
association: DimensionAssociationInput::Infer(self.source_handle),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -5,7 +5,7 @@ use cadkernel::geom2d::{
|
|||
closest_point, Circle as KernelCircle, Curve, Line as KernelLine,
|
||||
};
|
||||
|
||||
use crate::command::{CadCommand, CmdResult, WorkingPlane};
|
||||
use crate::command::{CadCommand, CmdResult, DimensionAssociationInput, WorkingPlane};
|
||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
use glam::DVec3;
|
||||
|
|
@ -186,7 +186,7 @@ impl CadCommand for LinearDimensionCommand {
|
|||
));
|
||||
CmdResult::CommitDimension {
|
||||
entity,
|
||||
source: self.source_handle,
|
||||
association: DimensionAssociationInput::Infer(self.source_handle),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,10 +6,12 @@ use acadrust::objects::{
|
|||
use acadrust::types::{Handle, Vector3};
|
||||
use acadrust::EntityType;
|
||||
use cadkernel::geom2d::{
|
||||
closest_point, Circle as KernelCircle, Curve as KernelCurve,
|
||||
closest_point, BulgeArc, Circle as KernelCircle, Curve as KernelCurve,
|
||||
};
|
||||
use std::f64::consts::TAU;
|
||||
|
||||
use crate::command::DimensionAssociationSource;
|
||||
|
||||
use super::{ChangeKind, Scene};
|
||||
|
||||
fn point_distance_squared(first: Vector3, second: Vector3) -> f64 {
|
||||
|
|
@ -34,10 +36,66 @@ fn circle_curve(circle: &acadrust::entities::Circle) -> KernelCurve {
|
|||
})
|
||||
}
|
||||
|
||||
fn bulge_center_world(
|
||||
first: [f64; 2],
|
||||
second: [f64; 2],
|
||||
bulge: f64,
|
||||
elevation: f64,
|
||||
normal: Vector3,
|
||||
) -> Option<Vector3> {
|
||||
let center = BulgeArc::from_bulge(first, second, bulge)?.center;
|
||||
Some(ocs_point(center[0], center[1], elevation, normal))
|
||||
}
|
||||
|
||||
fn next_segment_index(count: usize, closed: bool, segment: usize) -> Option<usize> {
|
||||
if segment + 1 < count {
|
||||
Some(segment + 1)
|
||||
} else if closed && segment < count {
|
||||
Some(0)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn polyline_arc_center(entity: &EntityType, segment: usize) -> Option<Vector3> {
|
||||
match entity {
|
||||
EntityType::LwPolyline(polyline) => {
|
||||
let count = polyline.vertices.len();
|
||||
let first = *polyline.vertices.get(segment)?;
|
||||
let second = *polyline
|
||||
.vertices
|
||||
.get(next_segment_index(count, polyline.is_closed, segment)?)?;
|
||||
bulge_center_world(
|
||||
[first.location.x, first.location.y],
|
||||
[second.location.x, second.location.y],
|
||||
first.bulge,
|
||||
polyline.elevation,
|
||||
polyline.normal,
|
||||
)
|
||||
}
|
||||
EntityType::Polyline2D(polyline) => {
|
||||
let count = polyline.vertices.len();
|
||||
let first = polyline.vertices.get(segment)?;
|
||||
let second = polyline
|
||||
.vertices
|
||||
.get(next_segment_index(count, polyline.is_closed(), segment)?)?;
|
||||
bulge_center_world(
|
||||
[first.location.x, first.location.y],
|
||||
[second.location.x, second.location.y],
|
||||
first.bulge,
|
||||
polyline.elevation,
|
||||
polyline.normal,
|
||||
)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn source_points(entity: &EntityType) -> Vec<Vector3> {
|
||||
match entity {
|
||||
EntityType::Line(line) => vec![line.start, line.end],
|
||||
EntityType::Arc(arc) => vec![arc.start_point_wcs(), arc.end_point_wcs()],
|
||||
EntityType::Circle(_) => Vec::new(),
|
||||
EntityType::LwPolyline(polyline) => polyline
|
||||
.vertices
|
||||
.iter()
|
||||
|
|
@ -66,10 +124,38 @@ fn source_points(entity: &EntityType) -> Vec<Vector3> {
|
|||
}
|
||||
}
|
||||
|
||||
fn source_marker(entity: &EntityType, point: Vector3) -> Option<i32> {
|
||||
if matches!(entity, EntityType::Circle(_)) {
|
||||
return Some(0);
|
||||
fn source_reference(entity: &EntityType, point: Vector3) -> Option<(i32, f64)> {
|
||||
let curve_parameter = match entity {
|
||||
EntityType::Circle(circle) => {
|
||||
let center = circle.center_wcs();
|
||||
if point_distance_squared(center, point) <= 1e-16 {
|
||||
return Some((-3, 0.0));
|
||||
}
|
||||
let (axis_x, axis_y) = circle.axes_wcs();
|
||||
let offset = point - center;
|
||||
Some(offset.dot(&axis_y).atan2(offset.dot(&axis_x)))
|
||||
}
|
||||
EntityType::Arc(arc) => {
|
||||
let local = crate::scene::view::transform::wcs_point_to_ocs(
|
||||
(point.x, point.y, point.z),
|
||||
(arc.normal.x, arc.normal.y, arc.normal.z),
|
||||
);
|
||||
let dx = local.0 - arc.center.x;
|
||||
let dy = local.1 - arc.center.y;
|
||||
if dx * dx + dy * dy <= 1e-16 {
|
||||
return Some((-3, 0.0));
|
||||
}
|
||||
Some(dy.atan2(dx))
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
if let Some(parameter) = curve_parameter {
|
||||
return Some((-2, parameter));
|
||||
}
|
||||
source_marker(entity, point).map(|marker| (marker, 0.0))
|
||||
}
|
||||
|
||||
fn source_marker(entity: &EntityType, point: Vector3) -> Option<i32> {
|
||||
source_points(entity)
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
|
|
@ -83,6 +169,26 @@ fn source_marker(entity: &EntityType, point: Vector3) -> Option<i32> {
|
|||
fn resolve_reference(scene: &Scene, reference: &AssocDimensionReference) -> Option<Vector3> {
|
||||
let source = *reference.xrefs.first()?;
|
||||
let entity = scene.document.get_entity(source)?;
|
||||
if reference.main_gs_marker == -4 {
|
||||
let segment = reference.osnap_distance.round().max(0.0) as usize;
|
||||
return polyline_arc_center(entity, segment);
|
||||
}
|
||||
if reference.main_gs_marker == -3 {
|
||||
return match entity {
|
||||
EntityType::Circle(circle) => Some(circle.center_wcs()),
|
||||
EntityType::Arc(arc) => Some(arc.center_wcs()),
|
||||
_ => None,
|
||||
};
|
||||
}
|
||||
if reference.main_gs_marker == -2 {
|
||||
return match entity {
|
||||
EntityType::Circle(circle) => {
|
||||
Some(circle.point_at_angle_wcs(reference.osnap_distance))
|
||||
}
|
||||
EntityType::Arc(arc) => Some(arc.point_at_angle_wcs(reference.osnap_distance)),
|
||||
_ => None,
|
||||
};
|
||||
}
|
||||
if let EntityType::Circle(circle) = entity {
|
||||
let stored = crate::scene::view::transform::wcs_point_to_ocs(
|
||||
(
|
||||
|
|
@ -115,7 +221,7 @@ fn resolve_reference(scene: &Scene, reference: &AssocDimensionReference) -> Opti
|
|||
.copied()
|
||||
}
|
||||
|
||||
fn dimension_points(dimension: &Dimension) -> Option<[Vector3; 2]> {
|
||||
fn dimension_inference_points(dimension: &Dimension) -> Option<[Vector3; 2]> {
|
||||
match dimension {
|
||||
Dimension::Linear(linear) => Some([linear.first_point, linear.second_point]),
|
||||
Dimension::Aligned(aligned) => Some([aligned.first_point, aligned.second_point]),
|
||||
|
|
@ -139,15 +245,23 @@ fn source_distance_squared(entity: &EntityType, point: Vector3) -> Option<f64> {
|
|||
.min_by(f64::total_cmp)
|
||||
}
|
||||
|
||||
fn source_parameter(entity: &EntityType, point: Vector3) -> f64 {
|
||||
let EntityType::Circle(circle) = entity else {
|
||||
return 0.0;
|
||||
};
|
||||
let point = crate::scene::view::transform::wcs_point_to_ocs(
|
||||
(point.x, point.y, point.z),
|
||||
(circle.normal.x, circle.normal.y, circle.normal.z),
|
||||
);
|
||||
circle_curve(circle).parameter_at([point.0, point.1]) * TAU
|
||||
fn dimension_reference_points(dimension: &Dimension) -> Vec<Vector3> {
|
||||
match dimension {
|
||||
Dimension::Linear(linear) => vec![linear.first_point, linear.second_point],
|
||||
Dimension::Aligned(aligned) => vec![aligned.first_point, aligned.second_point],
|
||||
Dimension::Angular3Pt(angular) => vec![
|
||||
angular.angle_vertex,
|
||||
angular.first_point,
|
||||
angular.second_point,
|
||||
],
|
||||
Dimension::Angular2Ln(angular) => vec![
|
||||
angular.first_point,
|
||||
angular.second_point,
|
||||
angular.angle_vertex,
|
||||
angular.definition_point,
|
||||
],
|
||||
_ => Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn dimension_is_associative(
|
||||
|
|
@ -176,31 +290,50 @@ impl Scene {
|
|||
pub(crate) fn attach_dimension_association(
|
||||
&mut self,
|
||||
dimension: Handle,
|
||||
sources: [Option<Handle>; 2],
|
||||
sources: Vec<Option<Handle>>,
|
||||
) {
|
||||
let Some(EntityType::Dimension(entity)) = self.document.get_entity(dimension)
|
||||
self.attach_dimension_association_sources(
|
||||
dimension,
|
||||
sources
|
||||
.into_iter()
|
||||
.map(|source| source.map(DimensionAssociationSource::inferred))
|
||||
.collect(),
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) fn attach_dimension_association_sources(
|
||||
&mut self,
|
||||
dimension: Handle,
|
||||
sources: Vec<Option<DimensionAssociationSource>>,
|
||||
) {
|
||||
let Some(EntityType::Dimension(dimension_entity)) =
|
||||
self.document.get_entity(dimension)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let Some(source_data) = dimension_points(entity) else {
|
||||
let source_data = dimension_reference_points(dimension_entity);
|
||||
if source_data.is_empty() {
|
||||
return;
|
||||
};
|
||||
let resolved: [Option<(Handle, i32, f64, u8)>; 2] = std::array::from_fn(|index| {
|
||||
let source = sources[index]?;
|
||||
let entity = self.document.get_entity(source)?;
|
||||
source_marker(entity, source_data[index]).map(|marker| {
|
||||
(
|
||||
source,
|
||||
marker,
|
||||
source_parameter(entity, source_data[index]),
|
||||
if matches!(entity, EntityType::Circle(_)) {
|
||||
10
|
||||
} else {
|
||||
1
|
||||
},
|
||||
)
|
||||
}
|
||||
let resolved: Vec<Option<(Handle, i32, f64, u8)>> = source_data
|
||||
.iter()
|
||||
.take(4)
|
||||
.enumerate()
|
||||
.map(|(index, point)| {
|
||||
let source = sources.get(index).copied().flatten()?;
|
||||
let entity = self.document.get_entity(source.handle)?;
|
||||
let (marker, parameter) = match source.marker {
|
||||
Some(marker) => (marker, source.parameter),
|
||||
None => source_reference(entity, *point)?,
|
||||
};
|
||||
let osnap_type = if matches!(entity, EntityType::Circle(_)) {
|
||||
10
|
||||
} else {
|
||||
1
|
||||
};
|
||||
Some((source.handle, marker, parameter, osnap_type))
|
||||
})
|
||||
});
|
||||
.collect();
|
||||
if resolved.iter().all(Option::is_none) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -223,6 +356,9 @@ impl Scene {
|
|||
std::array::from_fn(|_| Vec::new());
|
||||
let mut associativity = 0;
|
||||
for (index, resolved) in resolved.into_iter().enumerate() {
|
||||
if index >= references.len() {
|
||||
break;
|
||||
}
|
||||
if let Some((source, marker, parameter, osnap_type)) = resolved {
|
||||
associativity |= 1 << index;
|
||||
references[index].push(reference(
|
||||
|
|
@ -250,7 +386,7 @@ impl Scene {
|
|||
.insert(association_handle, ObjectType::Associative(object));
|
||||
|
||||
let mut reactor_targets = vec![dimension];
|
||||
reactor_targets.extend(sources.into_iter().flatten());
|
||||
reactor_targets.extend(sources.into_iter().flatten().map(|source| source.handle));
|
||||
reactor_targets.sort_by_key(|handle| handle.value());
|
||||
reactor_targets.dedup();
|
||||
for handle in reactor_targets {
|
||||
|
|
@ -270,7 +406,7 @@ impl Scene {
|
|||
else {
|
||||
return [None, None];
|
||||
};
|
||||
let Some(points) = dimension_points(entity) else {
|
||||
let Some(points) = dimension_inference_points(entity) else {
|
||||
return [None, None];
|
||||
};
|
||||
points.map(|point| {
|
||||
|
|
@ -318,13 +454,12 @@ impl Scene {
|
|||
|
||||
let mut refreshed = Vec::new();
|
||||
for association in associations {
|
||||
let first = association.references[0]
|
||||
.first()
|
||||
.and_then(|reference| resolve_reference(self, reference));
|
||||
let second = association.references[1]
|
||||
.first()
|
||||
.and_then(|reference| resolve_reference(self, reference));
|
||||
if first.is_none() && second.is_none() {
|
||||
let resolved: [Option<Vector3>; 4] = std::array::from_fn(|index| {
|
||||
association.references[index]
|
||||
.first()
|
||||
.and_then(|reference| resolve_reference(self, reference))
|
||||
});
|
||||
if resolved.iter().all(Option::is_none) {
|
||||
continue;
|
||||
}
|
||||
let Some(EntityType::Dimension(dimension)) =
|
||||
|
|
@ -334,27 +469,53 @@ impl Scene {
|
|||
};
|
||||
match dimension {
|
||||
Dimension::Linear(linear) => {
|
||||
if let Some(first) = first {
|
||||
linear.first_point = first;
|
||||
if let Some(point) = resolved[0] {
|
||||
linear.first_point = point;
|
||||
}
|
||||
if let Some(second) = second {
|
||||
linear.second_point = second;
|
||||
if let Some(point) = resolved[1] {
|
||||
linear.second_point = point;
|
||||
}
|
||||
linear.base.actual_measurement = linear.measurement();
|
||||
linear.base.definition_point = linear.definition_point;
|
||||
}
|
||||
Dimension::Aligned(aligned) => {
|
||||
if let Some(first) = first {
|
||||
aligned.first_point = first;
|
||||
if let Some(point) = resolved[0] {
|
||||
aligned.first_point = point;
|
||||
}
|
||||
if let Some(second) = second {
|
||||
aligned.second_point = second;
|
||||
if let Some(point) = resolved[1] {
|
||||
aligned.second_point = point;
|
||||
}
|
||||
aligned.base.actual_measurement = aligned.measurement();
|
||||
aligned.base.definition_point = aligned.definition_point;
|
||||
}
|
||||
Dimension::Angular3Pt(angular) => {
|
||||
if let Some(point) = resolved[0] {
|
||||
angular.angle_vertex = point;
|
||||
}
|
||||
if let Some(point) = resolved[1] {
|
||||
angular.first_point = point;
|
||||
}
|
||||
if let Some(point) = resolved[2] {
|
||||
angular.second_point = point;
|
||||
}
|
||||
angular.base.definition_point = angular.definition_point;
|
||||
}
|
||||
Dimension::Angular2Ln(angular) => {
|
||||
if let Some(point) = resolved[0] {
|
||||
angular.first_point = point;
|
||||
}
|
||||
if let Some(point) = resolved[1] {
|
||||
angular.second_point = point;
|
||||
}
|
||||
if let Some(point) = resolved[2] {
|
||||
angular.angle_vertex = point;
|
||||
}
|
||||
if let Some(point) = resolved[3] {
|
||||
angular.definition_point = point;
|
||||
}
|
||||
angular.base.definition_point = angular.definition_point;
|
||||
}
|
||||
_ => continue,
|
||||
}
|
||||
dimension.base_mut().actual_measurement = dimension.measurement();
|
||||
refreshed.push((association.dimension, ChangeKind::Modified));
|
||||
}
|
||||
refreshed
|
||||
|
|
|
|||
Loading…
Reference in a new issue