forked from 1b-agent/opencadstudio-upstream
Merge upstream main; follow the boxed MText codec type and the updated palette branch
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
8f20f0aef6
119 files changed
+560
-1020
No files matched your search
Generated
+36
-8
@@ -2397,7 +2397,7 @@ dependencies = [
|
|||||||
"hayro-syntax",
|
"hayro-syntax",
|
||||||
"kurbo 0.13.1",
|
"kurbo 0.13.1",
|
||||||
"moxcms",
|
"moxcms",
|
||||||
"phf",
|
"phf 0.13.1",
|
||||||
"rustc-hash 2.1.3",
|
"rustc-hash 2.1.3",
|
||||||
"siphasher",
|
"siphasher",
|
||||||
"skrifa 0.42.1",
|
"skrifa 0.42.1",
|
||||||
@@ -4348,6 +4348,15 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "oem_cp"
|
||||||
|
version = "2.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8c7959d3349f484aec36462f98226983578bf7d33f9b034c32967489c7000e1f"
|
||||||
|
dependencies = [
|
||||||
|
"phf 0.11.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.21.4"
|
version = "1.21.4"
|
||||||
@@ -4373,7 +4382,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opencadcodec"
|
name = "opencadcodec"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
source = "git+https://github.com/ramox81/cadcodec.git?rev=6434df7#6434df7049b4b81e66b8884180587efda343e070"
|
source = "git+https://github.com/ramox81/cadcodec.git?rev=67d53cb#67d53cb769d0db90302c24113553d87f8a997fee"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bitflags 2.13.1",
|
"bitflags 2.13.1",
|
||||||
@@ -4385,6 +4394,7 @@ dependencies = [
|
|||||||
"itoa",
|
"itoa",
|
||||||
"memmap2",
|
"memmap2",
|
||||||
"nom 7.1.3",
|
"nom 7.1.3",
|
||||||
|
"oem_cp",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rayon",
|
"rayon",
|
||||||
"ryu",
|
"ryu",
|
||||||
@@ -4396,7 +4406,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opencadgraph"
|
name = "opencadgraph"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/HakanSeven12/opencadgraph.git?rev=88cdae0#88cdae06858f6811f5058a5686bc1edb5ff39910"
|
source = "git+https://github.com/HakanSeven12/opencadgraph.git?rev=5d4e713#5d4e713968bd515be15302079d9edc1fd3df4df0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"opencadkernel",
|
"opencadkernel",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@@ -4405,7 +4415,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opencadkernel"
|
name = "opencadkernel"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/HakanSeven12/opencadkernel.git?rev=5811296#5811296a6c98ea9b12defa977f08d74cfc739014"
|
source = "git+https://github.com/HakanSeven12/opencadkernel.git?rev=dfca391#dfca3912228b19d4df25c8695b628ccb13497a78"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cavalier_contours",
|
"cavalier_contours",
|
||||||
"opencadcodec",
|
"opencadcodec",
|
||||||
@@ -4416,7 +4426,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opencadkernel-constraints"
|
name = "opencadkernel-constraints"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/HakanSeven12/opencadkernel.git?rev=5811296#5811296a6c98ea9b12defa977f08d74cfc739014"
|
source = "git+https://github.com/HakanSeven12/opencadkernel.git?rev=dfca391#dfca3912228b19d4df25c8695b628ccb13497a78"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nalgebra",
|
"nalgebra",
|
||||||
]
|
]
|
||||||
@@ -4595,6 +4605,15 @@ dependencies = [
|
|||||||
"indexmap",
|
"indexmap",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf"
|
||||||
|
version = "0.11.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
|
||||||
|
dependencies = [
|
||||||
|
"phf_shared 0.11.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "phf"
|
name = "phf"
|
||||||
version = "0.13.1"
|
version = "0.13.1"
|
||||||
@@ -4602,7 +4621,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf"
|
checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"phf_macros",
|
"phf_macros",
|
||||||
"phf_shared",
|
"phf_shared 0.13.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -4612,7 +4631,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737"
|
checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fastrand",
|
"fastrand",
|
||||||
"phf_shared",
|
"phf_shared 0.13.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -4622,12 +4641,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef"
|
checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"phf_generator",
|
"phf_generator",
|
||||||
"phf_shared",
|
"phf_shared 0.13.1",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.119",
|
"syn 2.0.119",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_shared"
|
||||||
|
version = "0.11.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
|
||||||
|
dependencies = [
|
||||||
|
"siphasher",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "phf_shared"
|
name = "phf_shared"
|
||||||
version = "0.13.1"
|
version = "0.13.1"
|
||||||
|
|||||||
+5
-5
@@ -37,10 +37,10 @@ rfd = "0.17"
|
|||||||
clap = { version = "4", features = ["derive", "string"] }
|
clap = { version = "4", features = ["derive", "string"] }
|
||||||
env_logger = "0.11"
|
env_logger = "0.11"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "102f04c", features = ["serde"] }
|
codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "325fa98", features = ["serde"] }
|
||||||
kernel = { package = "opencadkernel", git = "https://github.com/HakanSeven12/opencadkernel.git", rev = "5811296", features = ["acis", "offset"] }
|
kernel = { package = "opencadkernel", git = "https://github.com/HakanSeven12/opencadkernel.git", rev = "dfca391", features = ["acis", "offset"] }
|
||||||
kernel-constraints = { package = "opencadkernel-constraints", git = "https://github.com/HakanSeven12/opencadkernel.git", rev = "5811296" }
|
kernel-constraints = { package = "opencadkernel-constraints", git = "https://github.com/HakanSeven12/opencadkernel.git", rev = "dfca391" }
|
||||||
graph = { package = "opencadgraph", git = "https://github.com/HakanSeven12/opencadgraph.git", rev = "88cdae0" }
|
graph = { package = "opencadgraph", git = "https://github.com/HakanSeven12/opencadgraph.git", rev = "5d4e713" }
|
||||||
dwg-thumbnailer = { path = "crates/dwg-thumbnailer" }
|
dwg-thumbnailer = { path = "crates/dwg-thumbnailer" }
|
||||||
# Shared SAVE serialization dispatch + web-worker wire format: one
|
# Shared SAVE serialization dispatch + web-worker wire format: one
|
||||||
# implementation for the inline (fallback/native) path and the worker path.
|
# implementation for the inline (fallback/native) path and the worker path.
|
||||||
@@ -224,4 +224,4 @@ name = "integration"
|
|||||||
path = "tests/integration.rs"
|
path = "tests/integration.rs"
|
||||||
|
|
||||||
[patch."https://github.com/HakanSeven12/opencadcodec.git"]
|
[patch."https://github.com/HakanSeven12/opencadcodec.git"]
|
||||||
opencadcodec = { git = "https://github.com/ramox81/cadcodec.git", rev = "6434df7" }
|
opencadcodec = { git = "https://github.com/ramox81/cadcodec.git", rev = "67d53cb" }
|
||||||
@@ -101,7 +101,7 @@ fn push_fixture_entities(doc: &mut CadDocument, quick: bool) -> Vec<Handle> {
|
|||||||
d.definition_point = Vector3::new(x + 5.0, y + 3.0, 0.0);
|
d.definition_point = Vector3::new(x + 5.0, y + 3.0, 0.0);
|
||||||
d.base.text_middle_point = Vector3::new(x + 5.0, y + 4.0, 0.0);
|
d.base.text_middle_point = Vector3::new(x + 5.0, y + 4.0, 0.0);
|
||||||
handles.push(
|
handles.push(
|
||||||
doc.add_entity(EntityType::Dimension(Dimension::Linear(d)))
|
doc.add_entity(EntityType::Dimension(Box::new(Dimension::Linear(d))))
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ serde_json = { version = "1", optional = true }
|
|||||||
# Pulled in only by the `host` feature, which adds the `opencadcodec`-typed
|
# Pulled in only by the `host` feature, which adds the `opencadcodec`-typed
|
||||||
# `HostApi` runtime surface. The default crate stays dependency-free so engine
|
# `HostApi` runtime surface. The default crate stays dependency-free so engine
|
||||||
# crates and external tooling can depend on the manifest/ribbon contract cheaply.
|
# crates and external tooling can depend on the manifest/ribbon contract cheaply.
|
||||||
codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "102f04c", optional = true, features = ["serde"] }
|
codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "325fa98", optional = true, features = ["serde"] }
|
||||||
|
|
||||||
# Runtime IPC and serialization (host feature only).
|
# Runtime IPC and serialization (host feature only).
|
||||||
interprocess = { version = "2", optional = true }
|
interprocess = { version = "2", optional = true }
|
||||||
@@ -39,7 +39,7 @@ serde_json = "1"
|
|||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
cargo-lock = "11"
|
cargo-lock = "11"
|
||||||
# opencadcodec is scanned at build time to generate the embedded type registry.
|
# opencadcodec is scanned at build time to generate the embedded type registry.
|
||||||
codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "102f04c", features = ["serde"] }
|
codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "325fa98", features = ["serde"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
@@ -3583,7 +3583,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn unsupported_canvas_kind_has_typed_snapshot_fields() {
|
fn unsupported_canvas_kind_has_typed_snapshot_fields() {
|
||||||
use crate::host::codec;
|
use crate::host::codec;
|
||||||
let hatch = codec::EntityType::Hatch(codec::entities::Hatch::default());
|
let hatch = codec::EntityType::Hatch(Box::new(codec::entities::Hatch::default()));
|
||||||
let snapshot = entity_snapshot(&hatch).unwrap();
|
let snapshot = entity_snapshot(&hatch).unwrap();
|
||||||
let fields = snapshot
|
let fields = snapshot
|
||||||
.get("Hatch")
|
.get("Hatch")
|
||||||
@@ -3713,7 +3713,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn canvas_layer_patch_preserves_unmapped_hatch_fields() {
|
fn canvas_layer_patch_preserves_unmapped_hatch_fields() {
|
||||||
use crate::host::codec;
|
use crate::host::codec;
|
||||||
let hatch = codec::EntityType::Hatch(codec::entities::Hatch::default());
|
let hatch = codec::EntityType::Hatch(Box::new(codec::entities::Hatch::default()));
|
||||||
let patched = patch_canvas_layer(&hatch, "HATCHES").unwrap();
|
let patched = patch_canvas_layer(&hatch, "HATCHES").unwrap();
|
||||||
assert_eq!(patched.common().layer, "HATCHES");
|
assert_eq!(patched.common().layer, "HATCHES");
|
||||||
assert_eq!(hatch.common().layer, "0");
|
assert_eq!(hatch.common().layer, "0");
|
||||||
@@ -3809,13 +3809,13 @@ mod tests {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
hatch.paths.push(path);
|
hatch.paths.push(path);
|
||||||
let entity = codec::EntityType::Hatch(hatch.clone());
|
let entity = codec::EntityType::Hatch(Box::new(hatch.clone()));
|
||||||
validate_new_canvas_entity(&entity).unwrap();
|
validate_new_canvas_entity(&entity).unwrap();
|
||||||
|
|
||||||
let mut invalid = hatch.clone();
|
let mut invalid = hatch.clone();
|
||||||
invalid.paths.clear();
|
invalid.paths.clear();
|
||||||
assert!(
|
assert!(
|
||||||
validate_new_canvas_entity(&codec::EntityType::Hatch(invalid))
|
validate_new_canvas_entity(&codec::EntityType::Hatch(Box::new(invalid)))
|
||||||
.unwrap_err()
|
.unwrap_err()
|
||||||
.contains("at least one boundary path")
|
.contains("at least one boundary path")
|
||||||
);
|
);
|
||||||
@@ -3824,7 +3824,7 @@ mod tests {
|
|||||||
invalid.is_solid = false;
|
invalid.is_solid = false;
|
||||||
invalid.pattern_scale = 0.0;
|
invalid.pattern_scale = 0.0;
|
||||||
assert!(
|
assert!(
|
||||||
validate_new_canvas_entity(&codec::EntityType::Hatch(invalid))
|
validate_new_canvas_entity(&codec::EntityType::Hatch(Box::new(invalid)))
|
||||||
.unwrap_err()
|
.unwrap_err()
|
||||||
.contains("greater than zero")
|
.contains("greater than zero")
|
||||||
);
|
);
|
||||||
@@ -3841,13 +3841,13 @@ mod tests {
|
|||||||
associative.paths[0].boundary_handles.push(boundary);
|
associative.paths[0].boundary_handles.push(boundary);
|
||||||
validate_canvas_entity_references(
|
validate_canvas_entity_references(
|
||||||
&document,
|
&document,
|
||||||
&codec::EntityType::Hatch(associative.clone()),
|
&codec::EntityType::Hatch(Box::new(associative.clone())),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
associative.paths[0].boundary_handles[0] = codec::Handle::new(u64::MAX);
|
associative.paths[0].boundary_handles[0] = codec::Handle::new(u64::MAX);
|
||||||
assert!(validate_canvas_entity_references(
|
assert!(validate_canvas_entity_references(
|
||||||
&document,
|
&document,
|
||||||
&codec::EntityType::Hatch(associative),
|
&codec::EntityType::Hatch(Box::new(associative)),
|
||||||
)
|
)
|
||||||
.unwrap_err()
|
.unwrap_err()
|
||||||
.contains("does not exist"));
|
.contains("does not exist"));
|
||||||
|
|||||||
@@ -10,6 +10,6 @@ publish = false
|
|||||||
# exactly one implementation. No UI/app dependencies — only the codec + serde.
|
# exactly one implementation. No UI/app dependencies — only the codec + serde.
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "102f04c", features = ["serde"] }
|
codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "325fa98", features = ["serde"] }
|
||||||
bincode = "1.3"
|
bincode = "1.3"
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
@@ -8,7 +8,7 @@ publish = false
|
|||||||
crate-type = ["cdylib"]
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "102f04c", features = ["serde"] }
|
codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "325fa98", features = ["serde"] }
|
||||||
bincode = "1.3"
|
bincode = "1.3"
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
console_error_panic_hook = "0.1"
|
console_error_panic_hook = "0.1"
|
||||||
|
|||||||
@@ -16,4 +16,4 @@ ocs_plugin_api = { path = "../../crates/ocs_plugin_api", features = ["host"] }
|
|||||||
# entry): the plugin's entities and the host's re-exports are the same types
|
# entry): the plugin's entities and the host's re-exports are the same types
|
||||||
# only when both resolve the same revision. The registration `rustc` /
|
# only when both resolve the same revision. The registration `rustc` /
|
||||||
# `acadrust_source` gates enforce this at load time too.
|
# `acadrust_source` gates enforce this at load time too.
|
||||||
acadrust = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "102f04c" }
|
acadrust = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "325fa98" }
|
||||||
@@ -225,9 +225,7 @@ recovery =
|
|||||||
.failed-description = تعذر على الاسترداد إنتاج بيانات رسم قابلة للاستخدام. راجع التقرير وجرّب نسخة احتياطية أو نسخة حفظ تلقائي.
|
.failed-description = تعذر على الاسترداد إنتاج بيانات رسم قابلة للاستخدام. راجع التقرير وجرّب نسخة احتياطية أو نسخة حفظ تلقائي.
|
||||||
.entities-checked = الكيانات التي تم فحصها
|
.entities-checked = الكيانات التي تم فحصها
|
||||||
.issues-found = المشكلات الموجودة
|
.issues-found = المشكلات الموجودة
|
||||||
.entities-removed = الكيانات التي تمت إزالتها
|
|
||||||
.references-checked = المراجع التي تم فحصها
|
.references-checked = المراجع التي تم فحصها
|
||||||
.referenced-entities-removed = الكيانات المرجعية التي تمت إزالتها
|
|
||||||
.references-unavailable = المراجع غير المتاحة
|
.references-unavailable = المراجع غير المتاحة
|
||||||
.log-path = سجل الاسترداد
|
.log-path = سجل الاسترداد
|
||||||
.log-write-failed = تعذرت كتابة سجل الاسترداد
|
.log-write-failed = تعذرت كتابة سجل الاسترداد
|
||||||
@@ -2603,8 +2601,6 @@ file =
|
|||||||
.usage-undo-number-of-steps = الاستخدام: UNDO [number of steps]
|
.usage-undo-number-of-steps = الاستخدام: UNDO [number of steps]
|
||||||
.used-for-the-first-save-of-a-new-drawing-exist = يُستخدم للحفظ الأول لرسم جديد. تحتفظ الرسومات الحالية بنوع ملفها وإصدارها.
|
.used-for-the-first-save-of-a-new-drawing-exist = يُستخدم للحفظ الأول لرسم جديد. تحتفظ الرسومات الحالية بنوع ملفها وإصدارها.
|
||||||
.visual-style-label = النمط المرئي: __ocs_fmt_0__.
|
.visual-style-label = النمط المرئي: __ocs_fmt_0__.
|
||||||
.warning-corrupt-entities-dropped-parser-junk-b = تحذير: أُسقط __ocs_fmt_0__ كيان تالف (بيانات تحليل غير صالحة — اتجاهات/أعداد سيئة)
|
|
||||||
.warning-corrupt-xref-entities-dropped = تحذير: أُسقط __ocs_fmt_0__ كيان مرجع خارجي تالف
|
|
||||||
.xref-loaded = XREF حُمّل "__ocs_fmt_0__"
|
.xref-loaded = XREF حُمّل "__ocs_fmt_0__"
|
||||||
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: لا يمكن إنشاء ZIP الإرسال (__ocs_fmt_1__).
|
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: لا يمكن إنشاء ZIP الإرسال (__ocs_fmt_1__).
|
||||||
.cmd-cannot-create-folder-e = __ocs_fmt_0__: تعذر إنشاء المجلد (__ocs_fmt_1__).
|
.cmd-cannot-create-folder-e = __ocs_fmt_0__: تعذر إنشاء المجلد (__ocs_fmt_1__).
|
||||||
@@ -5650,9 +5646,9 @@ styles =
|
|||||||
.aci-color-index = فهرس ألوان ACI
|
.aci-color-index = فهرس ألوان ACI
|
||||||
.aci = ACI:
|
.aci = ACI:
|
||||||
.audit-no-issues-found = AUDIT: لم يُعثر على مشكلات.
|
.audit-no-issues-found = AUDIT: لم يُعثر على مشكلات.
|
||||||
.audit-reference-s-to-undefined-block-s = AUDIT: مراجع إلى كتل غير معرّفة: __ocs_fmt_0__
|
.audit-fix-any-errors-detected = AUDIT هل تريد إصلاح الأخطاء المكتشفة؟ [نعم / لا] <لا>:
|
||||||
.audit-reference-s-to-undefined-layer-s = AUDIT: مراجع إلى طبقات غير معرّفة: __ocs_fmt_0__
|
.audit-error-s-warning-s-found = AUDIT: تم العثور على __ocs_fmt_0__ خطأ و__ocs_fmt_1__ تحذير.
|
||||||
.audit-report-only-no-automatic-repair-performe = AUDIT: تقرير فقط — لم يُجرَ إصلاح تلقائي.
|
.audit-repair-s-applied-issue-s-left = AUDIT: تم تطبيق __ocs_fmt_0__ إصلاح، و__ocs_fmt_1__ مشكلة بلا حل.
|
||||||
.audit-scanned-total-object-s = AUDIT: فُحص __ocs_fmt_0__ كائن.
|
.audit-scanned-total-object-s = AUDIT: فُحص __ocs_fmt_0__ كائن.
|
||||||
.above-text = أعلى النص
|
.above-text = أعلى النص
|
||||||
.active-dim-style-set-to-name-arg = عُيّن نمط الأبعاد النشط إلى "__ocs_fmt_0__"
|
.active-dim-style-set-to-name-arg = عُيّن نمط الأبعاد النشط إلى "__ocs_fmt_0__"
|
||||||
|
|||||||
@@ -225,9 +225,7 @@ recovery =
|
|||||||
.failed-description = Възстановяването не успя да генерира използваеми чертожни данни. Прегледай отчета и опитай резервно копие или копие от автоматично запазване.
|
.failed-description = Възстановяването не успя да генерира използваеми чертожни данни. Прегледай отчета и опитай резервно копие или копие от автоматично запазване.
|
||||||
.entities-checked = Проверени обекти
|
.entities-checked = Проверени обекти
|
||||||
.issues-found = Открити проблеми
|
.issues-found = Открити проблеми
|
||||||
.entities-removed = Премахнати обекти
|
|
||||||
.references-checked = Проверени препратки
|
.references-checked = Проверени препратки
|
||||||
.referenced-entities-removed = Премахнати препратени обекти
|
|
||||||
.references-unavailable = Препратките не са налични
|
.references-unavailable = Препратките не са налични
|
||||||
.log-path = Дневник за възстановяване
|
.log-path = Дневник за възстановяване
|
||||||
.log-write-failed = Дневникът за възстановяване не можа да бъде записан
|
.log-write-failed = Дневникът за възстановяване не можа да бъде записан
|
||||||
@@ -2590,8 +2588,6 @@ file =
|
|||||||
.usage-undo-number-of-steps = Употреба: UNDO [брой стъпки]
|
.usage-undo-number-of-steps = Употреба: UNDO [брой стъпки]
|
||||||
.used-for-the-first-save-of-a-new-drawing-exist = Използва се при първото запазване на нов чертеж. Съществуващите чертежи запазват своя тип файл и версия.
|
.used-for-the-first-save-of-a-new-drawing-exist = Използва се при първото запазване на нов чертеж. Съществуващите чертежи запазват своя тип файл и версия.
|
||||||
.visual-style-label = Визуален стил: __ocs_fmt_0__.
|
.visual-style-label = Визуален стил: __ocs_fmt_0__.
|
||||||
.warning-corrupt-entities-dropped-parser-junk-b = Предупреждение: __ocs_fmt_0__ повредени обекта отхвърлени (грешка в анализатора — лоши нормали / брой)
|
|
||||||
.warning-corrupt-xref-entities-dropped = Предупреждение: __ocs_fmt_0__ повредени xref обекта отхвърлени
|
|
||||||
.xref-loaded = XREF Зареден "__ocs_fmt_0__"
|
.xref-loaded = XREF Зареден "__ocs_fmt_0__"
|
||||||
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: не може да се създаде ZIP за предаване (__ocs_fmt_1__).
|
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: не може да се създаде ZIP за предаване (__ocs_fmt_1__).
|
||||||
.cmd-cannot-create-folder-e = __ocs_fmt_0__: папката не може да бъде създадена (__ocs_fmt_1__).
|
.cmd-cannot-create-folder-e = __ocs_fmt_0__: папката не може да бъде създадена (__ocs_fmt_1__).
|
||||||
@@ -5638,9 +5634,9 @@ styles =
|
|||||||
.aci-color-index = ACI Цветови индекс
|
.aci-color-index = ACI Цветови индекс
|
||||||
.aci = ACI:
|
.aci = ACI:
|
||||||
.audit-no-issues-found = AUDIT: не са открити проблеми.
|
.audit-no-issues-found = AUDIT: не са открити проблеми.
|
||||||
.audit-reference-s-to-undefined-block-s = AUDIT: препратка/и към недефинирани блок(ове): __ocs_fmt_0__
|
.audit-fix-any-errors-detected = AUDIT Да се поправят ли откритите грешки? [Да / Не] <Не>:
|
||||||
.audit-reference-s-to-undefined-layer-s = AUDIT: препратка/и към недефинирани слой(еве): __ocs_fmt_0__
|
.audit-error-s-warning-s-found = AUDIT: открити грешки: __ocs_fmt_0__, предупреждения: __ocs_fmt_1__.
|
||||||
.audit-report-only-no-automatic-repair-performe = AUDIT: само отчет — не е извършена автоматична поправка.
|
.audit-repair-s-applied-issue-s-left = AUDIT: приложени поправки: __ocs_fmt_0__, нерешени проблеми: __ocs_fmt_1__.
|
||||||
.audit-scanned-total-object-s = AUDIT: сканирани __ocs_fmt_0__ обект(а).
|
.audit-scanned-total-object-s = AUDIT: сканирани __ocs_fmt_0__ обект(а).
|
||||||
.above-text = Над текста
|
.above-text = Над текста
|
||||||
.active-dim-style-set-to-name-arg = Активният стил за оразмеряване е зададен на "__ocs_fmt_0__"
|
.active-dim-style-set-to-name-arg = Активният стил за оразмеряване е зададен на "__ocs_fmt_0__"
|
||||||
|
|||||||
@@ -225,9 +225,7 @@ recovery =
|
|||||||
.failed-description = Při obnovení se nepodařilo získat použitelná data výkresu. Projděte zprávu a zkuste zálohu nebo automaticky uloženou kopii.
|
.failed-description = Při obnovení se nepodařilo získat použitelná data výkresu. Projděte zprávu a zkuste zálohu nebo automaticky uloženou kopii.
|
||||||
.entities-checked = Zkontrolované entity
|
.entities-checked = Zkontrolované entity
|
||||||
.issues-found = Nalezené problémy
|
.issues-found = Nalezené problémy
|
||||||
.entities-removed = Odstraněné entity
|
|
||||||
.references-checked = Zkontrolované reference
|
.references-checked = Zkontrolované reference
|
||||||
.referenced-entities-removed = Odstraněné odkazované entity
|
|
||||||
.references-unavailable = Nedostupné reference
|
.references-unavailable = Nedostupné reference
|
||||||
.log-path = Protokol obnovení
|
.log-path = Protokol obnovení
|
||||||
.log-write-failed = Protokol obnovení se nepodařilo zapsat
|
.log-write-failed = Protokol obnovení se nepodařilo zapsat
|
||||||
@@ -2590,8 +2588,6 @@ file =
|
|||||||
.usage-undo-number-of-steps = Použití: UNDO [počet kroků]
|
.usage-undo-number-of-steps = Použití: UNDO [počet kroků]
|
||||||
.used-for-the-first-save-of-a-new-drawing-exist = Používá se pro první uložení nového výkresu. Stávající výkresy si ponechají svůj typ souboru a verzi.
|
.used-for-the-first-save-of-a-new-drawing-exist = Používá se pro první uložení nového výkresu. Stávající výkresy si ponechají svůj typ souboru a verzi.
|
||||||
.visual-style-label = Vizuální styl: __ocs_fmt_0__.
|
.visual-style-label = Vizuální styl: __ocs_fmt_0__.
|
||||||
.warning-corrupt-entities-dropped-parser-junk-b = Varování: __ocs_fmt_0__ poškozené entity byly odstraněny (nevyžádaná analyzátor – špatné normály / počty)
|
|
||||||
.warning-corrupt-xref-entities-dropped = Varování: __ocs_fmt_0__ poškozené entity externí reference byly zrušeny
|
|
||||||
.xref-loaded = XREF Načteno "__ocs_fmt_0__"
|
.xref-loaded = XREF Načteno "__ocs_fmt_0__"
|
||||||
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: nelze vytvořit přenosový ZIP (__ocs_fmt_1__).
|
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: nelze vytvořit přenosový ZIP (__ocs_fmt_1__).
|
||||||
.cmd-cannot-create-folder-e = __ocs_fmt_0__: Nelze vytvořit složku (__ocs_fmt_1__).
|
.cmd-cannot-create-folder-e = __ocs_fmt_0__: Nelze vytvořit složku (__ocs_fmt_1__).
|
||||||
@@ -5635,9 +5631,9 @@ styles =
|
|||||||
.aci-color-index = Barevný index ACI
|
.aci-color-index = Barevný index ACI
|
||||||
.aci = ACI:
|
.aci = ACI:
|
||||||
.audit-no-issues-found = AUDIT: nebyly nalezeny žádné problémy.
|
.audit-no-issues-found = AUDIT: nebyly nalezeny žádné problémy.
|
||||||
.audit-reference-s-to-undefined-block-s = AUDIT: reference na nedefinované bloky: __ocs_fmt_0__
|
.audit-fix-any-errors-detected = AUDIT Opravit zjištěné chyby? [Ano / Ne] <Ne>:
|
||||||
.audit-reference-s-to-undefined-layer-s = AUDIT: reference na nedefinované vrstvy: __ocs_fmt_0__
|
.audit-error-s-warning-s-found = AUDIT: nalezeno chyb: __ocs_fmt_0__, varování: __ocs_fmt_1__.
|
||||||
.audit-report-only-no-automatic-repair-performe = AUDIT: pouze zpráva – neprovádí se žádná automatická oprava.
|
.audit-repair-s-applied-issue-s-left = AUDIT: provedeno oprav: __ocs_fmt_0__, nevyřešeno problémů: __ocs_fmt_1__.
|
||||||
.audit-scanned-total-object-s = AUDIT: skenovaný objekt(y) __ocs_fmt_0__.
|
.audit-scanned-total-object-s = AUDIT: skenovaný objekt(y) __ocs_fmt_0__.
|
||||||
.above-text = Nad textem
|
.above-text = Nad textem
|
||||||
.active-dim-style-set-to-name-arg = Styl aktivního ztlumení nastaven na "__ocs_fmt_0__"
|
.active-dim-style-set-to-name-arg = Styl aktivního ztlumení nastaven na "__ocs_fmt_0__"
|
||||||
|
|||||||
@@ -225,9 +225,7 @@ recovery =
|
|||||||
.failed-description = Die Wiederherstellung konnte keine verwendbaren Zeichnungsdaten erzeugen. Prüfen Sie den Bericht und versuchen Sie eine Sicherungskopie oder automatisch gespeicherte Kopie.
|
.failed-description = Die Wiederherstellung konnte keine verwendbaren Zeichnungsdaten erzeugen. Prüfen Sie den Bericht und versuchen Sie eine Sicherungskopie oder automatisch gespeicherte Kopie.
|
||||||
.entities-checked = Geprüfte Objekte
|
.entities-checked = Geprüfte Objekte
|
||||||
.issues-found = Gefundene Probleme
|
.issues-found = Gefundene Probleme
|
||||||
.entities-removed = Entfernte Objekte
|
|
||||||
.references-checked = Geprüfte Referenzen
|
.references-checked = Geprüfte Referenzen
|
||||||
.referenced-entities-removed = Entfernte referenzierte Objekte
|
|
||||||
.references-unavailable = Nicht verfügbare Referenzen
|
.references-unavailable = Nicht verfügbare Referenzen
|
||||||
.log-path = Wiederherstellungsprotokoll
|
.log-path = Wiederherstellungsprotokoll
|
||||||
.log-write-failed = Wiederherstellungsprotokoll konnte nicht geschrieben werden
|
.log-write-failed = Wiederherstellungsprotokoll konnte nicht geschrieben werden
|
||||||
@@ -2591,8 +2589,6 @@ file =
|
|||||||
.usage-undo-number-of-steps = Anwendung: UNDO [number of steps]
|
.usage-undo-number-of-steps = Anwendung: UNDO [number of steps]
|
||||||
.used-for-the-first-save-of-a-new-drawing-exist = Wird für die erste Speicherung einer neuen Zeichnung verwendet. Bestehende Zeichnungen behalten ihren Dateityp und ihre Version bei.
|
.used-for-the-first-save-of-a-new-drawing-exist = Wird für die erste Speicherung einer neuen Zeichnung verwendet. Bestehende Zeichnungen behalten ihren Dateityp und ihre Version bei.
|
||||||
.visual-style-label = Visueller Stil: __ocs_fmt_0__.
|
.visual-style-label = Visueller Stil: __ocs_fmt_0__.
|
||||||
.warning-corrupt-entities-dropped-parser-junk-b = Warnung: __ocs_fmt_0__ beschädigte Objekte verworfen (ungültige Analysedaten — fehlerhafte Normalen oder Anzahlen)
|
|
||||||
.warning-corrupt-xref-entities-dropped = Warnung: __ocs_fmt_0__ beschädigte XRef-Objekte verworfen
|
|
||||||
.xref-loaded = XREF Geladen "__ocs_fmt_0__"
|
.xref-loaded = XREF Geladen "__ocs_fmt_0__"
|
||||||
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: das Übertragungs-ZIP kann nicht erstellt werden (__ocs_fmt_1__).
|
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: das Übertragungs-ZIP kann nicht erstellt werden (__ocs_fmt_1__).
|
||||||
.cmd-cannot-create-folder-e = __ocs_fmt_0__: kann keinen Ordner erstellen (__ocs_fmt_1__).
|
.cmd-cannot-create-folder-e = __ocs_fmt_0__: kann keinen Ordner erstellen (__ocs_fmt_1__).
|
||||||
@@ -5636,9 +5632,9 @@ styles =
|
|||||||
.aci-color-index = ACI Farbindex
|
.aci-color-index = ACI Farbindex
|
||||||
.aci = ACI:
|
.aci = ACI:
|
||||||
.audit-no-issues-found = AUDIT: keine Probleme gefunden.
|
.audit-no-issues-found = AUDIT: keine Probleme gefunden.
|
||||||
.audit-reference-s-to-undefined-block-s = AUDIT: Verweis(e) auf undefinierte(n) Block(e): __ocs_fmt_0__
|
.audit-fix-any-errors-detected = AUDIT Gefundene Fehler beheben? [Ja / Nein] <Nein>:
|
||||||
.audit-reference-s-to-undefined-layer-s = AUDIT: Referenz(en) auf undefinierte Ebene(n): __ocs_fmt_0__
|
.audit-error-s-warning-s-found = AUDIT: __ocs_fmt_0__ Fehler, __ocs_fmt_1__ Warnung(en) gefunden.
|
||||||
.audit-report-only-no-automatic-repair-performe = AUDIT: Nur Bericht erstatten — keine automatische Reparatur durchgeführt.
|
.audit-repair-s-applied-issue-s-left = AUDIT: __ocs_fmt_0__ Reparatur(en) ausgeführt, __ocs_fmt_1__ Problem(e) ungelöst.
|
||||||
.audit-scanned-total-object-s = AUDIT: gescanntes __ocs_fmt_0__ Objekt(e).
|
.audit-scanned-total-object-s = AUDIT: gescanntes __ocs_fmt_0__ Objekt(e).
|
||||||
.above-text = Vorstehender Text
|
.above-text = Vorstehender Text
|
||||||
.active-dim-style-set-to-name-arg = Aktiver Bemaßungsstil auf „__ocs_fmt_0__“ gesetzt
|
.active-dim-style-set-to-name-arg = Aktiver Bemaßungsstil auf „__ocs_fmt_0__“ gesetzt
|
||||||
|
|||||||
@@ -224,9 +224,7 @@ recovery =
|
|||||||
.failed-description = Η ανάκτηση δεν μπόρεσε να παραγάγει αξιοποιήσιμα δεδομένα σχεδίου. Ελέγξτε την αναφορά και δοκιμάστε ένα αντίγραφο ασφαλείας ή αυτόματης αποθήκευσης.
|
.failed-description = Η ανάκτηση δεν μπόρεσε να παραγάγει αξιοποιήσιμα δεδομένα σχεδίου. Ελέγξτε την αναφορά και δοκιμάστε ένα αντίγραφο ασφαλείας ή αυτόματης αποθήκευσης.
|
||||||
.entities-checked = Οντότητες που ελέγχθηκαν
|
.entities-checked = Οντότητες που ελέγχθηκαν
|
||||||
.issues-found = Προβλήματα που βρέθηκαν
|
.issues-found = Προβλήματα που βρέθηκαν
|
||||||
.entities-removed = Οντότητες που αφαιρέθηκαν
|
|
||||||
.references-checked = Αναφορές που ελέγχθηκαν
|
.references-checked = Αναφορές που ελέγχθηκαν
|
||||||
.referenced-entities-removed = Αναφερόμενες οντότητες που αφαιρέθηκαν
|
|
||||||
.references-unavailable = Οι αναφορές δεν είναι διαθέσιμες
|
.references-unavailable = Οι αναφορές δεν είναι διαθέσιμες
|
||||||
.log-path = Αρχείο καταγραφής ανάκτησης
|
.log-path = Αρχείο καταγραφής ανάκτησης
|
||||||
.log-write-failed = Δεν ήταν δυνατή η εγγραφή του αρχείου καταγραφής ανάκτησης
|
.log-write-failed = Δεν ήταν δυνατή η εγγραφή του αρχείου καταγραφής ανάκτησης
|
||||||
@@ -2590,8 +2588,6 @@ file =
|
|||||||
.usage-undo-number-of-steps = Χρήση: UNDO [αριθμός βημάτων]
|
.usage-undo-number-of-steps = Χρήση: UNDO [αριθμός βημάτων]
|
||||||
.used-for-the-first-save-of-a-new-drawing-exist = Χρησιμοποιείται στην πρώτη αποθήκευση ενός νέου σχεδίου. Τα υπάρχοντα σχέδια διατηρούν τον τύπο και την έκδοση του αρχείου τους.
|
.used-for-the-first-save-of-a-new-drawing-exist = Χρησιμοποιείται στην πρώτη αποθήκευση ενός νέου σχεδίου. Τα υπάρχοντα σχέδια διατηρούν τον τύπο και την έκδοση του αρχείου τους.
|
||||||
.visual-style-label = Οπτικό στυλ: __ocs_fmt_0__.
|
.visual-style-label = Οπτικό στυλ: __ocs_fmt_0__.
|
||||||
.warning-corrupt-entities-dropped-parser-junk-b = Προειδοποίηση: απορρίφθηκαν __ocs_fmt_0__ κατεστραμμένες οντότητες (άχρηστα δεδομένα αναλυτή — εσφαλμένα κάθετα διανύσματα / πλήθη)
|
|
||||||
.warning-corrupt-xref-entities-dropped = Προειδοποίηση: απορρίφθηκαν __ocs_fmt_0__ κατεστραμμένες οντότητες xref
|
|
||||||
.xref-loaded = XREF Φορτώθηκε το "__ocs_fmt_0__"
|
.xref-loaded = XREF Φορτώθηκε το "__ocs_fmt_0__"
|
||||||
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: δεν είναι δυνατή η δημιουργία του ZIP μεταφοράς (__ocs_fmt_1__).
|
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: δεν είναι δυνατή η δημιουργία του ZIP μεταφοράς (__ocs_fmt_1__).
|
||||||
.cmd-cannot-create-folder-e = __ocs_fmt_0__: δεν είναι δυνατή η δημιουργία φακέλου (__ocs_fmt_1__).
|
.cmd-cannot-create-folder-e = __ocs_fmt_0__: δεν είναι δυνατή η δημιουργία φακέλου (__ocs_fmt_1__).
|
||||||
@@ -5638,9 +5634,9 @@ styles =
|
|||||||
.aci-color-index = Δείκτης χρώματος ACI
|
.aci-color-index = Δείκτης χρώματος ACI
|
||||||
.aci = ACI:
|
.aci = ACI:
|
||||||
.audit-no-issues-found = AUDIT: δεν βρέθηκαν προβλήματα.
|
.audit-no-issues-found = AUDIT: δεν βρέθηκαν προβλήματα.
|
||||||
.audit-reference-s-to-undefined-block-s = AUDIT: αναφορά(ές) σε μη ορισμένα μπλοκ: __ocs_fmt_0__
|
.audit-fix-any-errors-detected = AUDIT Διόρθωση των σφαλμάτων που εντοπίστηκαν; [Ναι / Όχι] <Όχι>:
|
||||||
.audit-reference-s-to-undefined-layer-s = AUDIT: αναφορά(ές) σε μη ορισμένα επίπεδα: __ocs_fmt_0__
|
.audit-error-s-warning-s-found = AUDIT: βρέθηκαν __ocs_fmt_0__ σφάλματα, __ocs_fmt_1__ προειδοποιήσεις.
|
||||||
.audit-report-only-no-automatic-repair-performe = AUDIT: μόνο αναφορά — δεν έγινε αυτόματη επιδιόρθωση.
|
.audit-repair-s-applied-issue-s-left = AUDIT: εφαρμόστηκαν __ocs_fmt_0__ επιδιορθώσεις, __ocs_fmt_1__ προβλήματα παραμένουν άλυτα.
|
||||||
.audit-scanned-total-object-s = AUDIT: σαρώθηκαν __ocs_fmt_0__ αντικείμενο(α).
|
.audit-scanned-total-object-s = AUDIT: σαρώθηκαν __ocs_fmt_0__ αντικείμενο(α).
|
||||||
.above-text = Πάνω από το κείμενο
|
.above-text = Πάνω από το κείμενο
|
||||||
.active-dim-style-set-to-name-arg = Το ενεργό στυλ διαστάσεων ορίστηκε σε "__ocs_fmt_0__"
|
.active-dim-style-set-to-name-arg = Το ενεργό στυλ διαστάσεων ορίστηκε σε "__ocs_fmt_0__"
|
||||||
|
|||||||
@@ -224,9 +224,7 @@ recovery =
|
|||||||
.failed-description = Recovery could not produce usable drawing data. Review the report and try a backup or automatic-save copy.
|
.failed-description = Recovery could not produce usable drawing data. Review the report and try a backup or automatic-save copy.
|
||||||
.entities-checked = Entities checked
|
.entities-checked = Entities checked
|
||||||
.issues-found = Issues found
|
.issues-found = Issues found
|
||||||
.entities-removed = Entities removed
|
|
||||||
.references-checked = References checked
|
.references-checked = References checked
|
||||||
.referenced-entities-removed = Referenced entities removed
|
|
||||||
.references-unavailable = References unavailable
|
.references-unavailable = References unavailable
|
||||||
.log-path = Recovery log
|
.log-path = Recovery log
|
||||||
.log-write-failed = Recovery log could not be written
|
.log-write-failed = Recovery log could not be written
|
||||||
@@ -2591,8 +2589,6 @@ file =
|
|||||||
.usage-undo-number-of-steps = Usage: UNDO [number of steps]
|
.usage-undo-number-of-steps = Usage: UNDO [number of steps]
|
||||||
.used-for-the-first-save-of-a-new-drawing-exist = Used for the first save of a new drawing. Existing drawings keep their file type and version.
|
.used-for-the-first-save-of-a-new-drawing-exist = Used for the first save of a new drawing. Existing drawings keep their file type and version.
|
||||||
.visual-style-label = Visual style: __ocs_fmt_0__.
|
.visual-style-label = Visual style: __ocs_fmt_0__.
|
||||||
.warning-corrupt-entities-dropped-parser-junk-b = Warning: __ocs_fmt_0__ corrupt entities dropped (parser junk — bad normals / counts)
|
|
||||||
.warning-corrupt-xref-entities-dropped = Warning: __ocs_fmt_0__ corrupt xref entities dropped
|
|
||||||
.xref-loaded = XREF Loaded "__ocs_fmt_0__"
|
.xref-loaded = XREF Loaded "__ocs_fmt_0__"
|
||||||
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: cannot build the transmittal ZIP (__ocs_fmt_1__).
|
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: cannot build the transmittal ZIP (__ocs_fmt_1__).
|
||||||
.cmd-cannot-create-folder-e = __ocs_fmt_0__: cannot create folder (__ocs_fmt_1__).
|
.cmd-cannot-create-folder-e = __ocs_fmt_0__: cannot create folder (__ocs_fmt_1__).
|
||||||
@@ -5637,9 +5633,9 @@ styles =
|
|||||||
.aci-color-index = ACI Color Index
|
.aci-color-index = ACI Color Index
|
||||||
.aci = ACI:
|
.aci = ACI:
|
||||||
.audit-no-issues-found = AUDIT: no issues found.
|
.audit-no-issues-found = AUDIT: no issues found.
|
||||||
.audit-reference-s-to-undefined-block-s = AUDIT: reference(s) to undefined block(s): __ocs_fmt_0__
|
.audit-fix-any-errors-detected = AUDIT Fix any errors detected? [Yes / No] <No>:
|
||||||
.audit-reference-s-to-undefined-layer-s = AUDIT: reference(s) to undefined layer(s): __ocs_fmt_0__
|
.audit-error-s-warning-s-found = AUDIT: __ocs_fmt_0__ error(s), __ocs_fmt_1__ warning(s) found.
|
||||||
.audit-report-only-no-automatic-repair-performe = AUDIT: report only — no automatic repair performed.
|
.audit-repair-s-applied-issue-s-left = AUDIT: __ocs_fmt_0__ repair(s) applied, __ocs_fmt_1__ issue(s) left unresolved.
|
||||||
.audit-scanned-total-object-s = AUDIT: scanned __ocs_fmt_0__ object(s).
|
.audit-scanned-total-object-s = AUDIT: scanned __ocs_fmt_0__ object(s).
|
||||||
.above-text = Above text
|
.above-text = Above text
|
||||||
.active-dim-style-set-to-name-arg = Active dim style set to "__ocs_fmt_0__"
|
.active-dim-style-set-to-name-arg = Active dim style set to "__ocs_fmt_0__"
|
||||||
|
|||||||
@@ -225,9 +225,7 @@ recovery =
|
|||||||
.failed-description = La recuperación no pudo producir datos de dibujo utilizables. Revise el informe e intente usar una copia de seguridad o de guardado automático.
|
.failed-description = La recuperación no pudo producir datos de dibujo utilizables. Revise el informe e intente usar una copia de seguridad o de guardado automático.
|
||||||
.entities-checked = Entidades comprobadas
|
.entities-checked = Entidades comprobadas
|
||||||
.issues-found = Problemas encontrados
|
.issues-found = Problemas encontrados
|
||||||
.entities-removed = Entidades eliminadas
|
|
||||||
.references-checked = Referencias comprobadas
|
.references-checked = Referencias comprobadas
|
||||||
.referenced-entities-removed = Entidades referenciadas eliminadas
|
|
||||||
.references-unavailable = Referencias no disponibles
|
.references-unavailable = Referencias no disponibles
|
||||||
.log-path = Registro de recuperación
|
.log-path = Registro de recuperación
|
||||||
.log-write-failed = No se pudo escribir el registro de recuperación
|
.log-write-failed = No se pudo escribir el registro de recuperación
|
||||||
@@ -2591,8 +2589,6 @@ file =
|
|||||||
.usage-undo-number-of-steps = Uso: UNDO [número de pasos]
|
.usage-undo-number-of-steps = Uso: UNDO [número de pasos]
|
||||||
.used-for-the-first-save-of-a-new-drawing-exist = Se usa para el primer guardado de un dibujo nuevo. Los dibujos existentes conservan su tipo y versión de archivo.
|
.used-for-the-first-save-of-a-new-drawing-exist = Se usa para el primer guardado de un dibujo nuevo. Los dibujos existentes conservan su tipo y versión de archivo.
|
||||||
.visual-style-label = Estilo visual: __ocs_fmt_0__.
|
.visual-style-label = Estilo visual: __ocs_fmt_0__.
|
||||||
.warning-corrupt-entities-dropped-parser-junk-b = Advertencia: se descartaron __ocs_fmt_0__ entidades dañadas (datos inválidos del analizador: normales o recuentos erróneos)
|
|
||||||
.warning-corrupt-xref-entities-dropped = Advertencia: se descartaron __ocs_fmt_0__ entidades de referencia externa dañadas
|
|
||||||
.xref-loaded = XREF Se cargó «__ocs_fmt_0__»
|
.xref-loaded = XREF Se cargó «__ocs_fmt_0__»
|
||||||
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: no se puede crear el ZIP de transmisión (__ocs_fmt_1__).
|
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: no se puede crear el ZIP de transmisión (__ocs_fmt_1__).
|
||||||
.cmd-cannot-create-folder-e = __ocs_fmt_0__: no se puede crear la carpeta (__ocs_fmt_1__).
|
.cmd-cannot-create-folder-e = __ocs_fmt_0__: no se puede crear la carpeta (__ocs_fmt_1__).
|
||||||
@@ -5638,9 +5634,9 @@ styles =
|
|||||||
.aci-color-index = Índice de color ACI
|
.aci-color-index = Índice de color ACI
|
||||||
.aci = ACI:
|
.aci = ACI:
|
||||||
.audit-no-issues-found = AUDIT: no se encontraron problemas.
|
.audit-no-issues-found = AUDIT: no se encontraron problemas.
|
||||||
.audit-reference-s-to-undefined-block-s = AUDIT: referencias a bloques no definidos: __ocs_fmt_0__
|
.audit-fix-any-errors-detected = AUDIT ¿Corregir los errores detectados? [Sí / No] <No>:
|
||||||
.audit-reference-s-to-undefined-layer-s = AUDIT: referencias a capas no definidas: __ocs_fmt_0__
|
.audit-error-s-warning-s-found = AUDIT: __ocs_fmt_0__ error(es), __ocs_fmt_1__ advertencia(s) encontrados.
|
||||||
.audit-report-only-no-automatic-repair-performe = AUDIT: solo informe; no se realizó ninguna reparación automática.
|
.audit-repair-s-applied-issue-s-left = AUDIT: __ocs_fmt_0__ reparación(es) aplicada(s), __ocs_fmt_1__ problema(s) sin resolver.
|
||||||
.audit-scanned-total-object-s = AUDIT: se examinaron __ocs_fmt_0__ objetos.
|
.audit-scanned-total-object-s = AUDIT: se examinaron __ocs_fmt_0__ objetos.
|
||||||
.above-text = Encima del texto
|
.above-text = Encima del texto
|
||||||
.active-dim-style-set-to-name-arg = Estilo de cota activo definido como «__ocs_fmt_0__»
|
.active-dim-style-set-to-name-arg = Estilo de cota activo definido como «__ocs_fmt_0__»
|
||||||
|
|||||||
@@ -225,9 +225,7 @@ recovery =
|
|||||||
.failed-description = Palautus ei tuottanut käyttökelpoisia piirustustietoja. Tarkista raportti ja kokeile varmuuskopiota tai automaattisesti tallennettua kopiota.
|
.failed-description = Palautus ei tuottanut käyttökelpoisia piirustustietoja. Tarkista raportti ja kokeile varmuuskopiota tai automaattisesti tallennettua kopiota.
|
||||||
.entities-checked = Tarkistetut entiteetit
|
.entities-checked = Tarkistetut entiteetit
|
||||||
.issues-found = Havaitut ongelmat
|
.issues-found = Havaitut ongelmat
|
||||||
.entities-removed = Poistetut entiteetit
|
|
||||||
.references-checked = Tarkistetut viitteet
|
.references-checked = Tarkistetut viitteet
|
||||||
.referenced-entities-removed = Poistetut viitatut entiteetit
|
|
||||||
.references-unavailable = Viitteet eivät ole käytettävissä
|
.references-unavailable = Viitteet eivät ole käytettävissä
|
||||||
.log-path = Palautusloki
|
.log-path = Palautusloki
|
||||||
.log-write-failed = Palautuslokia ei voitu kirjoittaa
|
.log-write-failed = Palautuslokia ei voitu kirjoittaa
|
||||||
@@ -2590,8 +2588,6 @@ file =
|
|||||||
.usage-undo-number-of-steps = Käyttö: UNDO [vaiheiden määrä]
|
.usage-undo-number-of-steps = Käyttö: UNDO [vaiheiden määrä]
|
||||||
.used-for-the-first-save-of-a-new-drawing-exist = Käytetään uuden piirustuksen ensimmäiseen tallennukseen. Olemassa olevat piirustukset säilyttävät tiedostotyyppinsä ja -versionsa.
|
.used-for-the-first-save-of-a-new-drawing-exist = Käytetään uuden piirustuksen ensimmäiseen tallennukseen. Olemassa olevat piirustukset säilyttävät tiedostotyyppinsä ja -versionsa.
|
||||||
.visual-style-label = Visuaalinen tyyli: __ocs_fmt_0__.
|
.visual-style-label = Visuaalinen tyyli: __ocs_fmt_0__.
|
||||||
.warning-corrupt-entities-dropped-parser-junk-b = Varoitus: __ocs_fmt_0__-korruptoituneet entiteetit pudotettiin (jäsennysroska - huonot normaalit / määrät)
|
|
||||||
.warning-corrupt-xref-entities-dropped = Varoitus: __ocs_fmt_0__-korruptoituneet xref-entiteetit putosivat
|
|
||||||
.xref-loaded = XREF Ladattu "__ocs_fmt_0__"
|
.xref-loaded = XREF Ladattu "__ocs_fmt_0__"
|
||||||
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: siirto-ZIP:n luominen epäonnistui (__ocs_fmt_1__).
|
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: siirto-ZIP:n luominen epäonnistui (__ocs_fmt_1__).
|
||||||
.cmd-cannot-create-folder-e = __ocs_fmt_0__: kansiota (__ocs_fmt_1__) ei voi luoda.
|
.cmd-cannot-create-folder-e = __ocs_fmt_0__: kansiota (__ocs_fmt_1__) ei voi luoda.
|
||||||
@@ -5637,9 +5633,9 @@ styles =
|
|||||||
.aci-color-index = ACI väriindeksi
|
.aci-color-index = ACI väriindeksi
|
||||||
.aci = ACI:
|
.aci = ACI:
|
||||||
.audit-no-issues-found = AUDIT: ongelmia ei löytynyt.
|
.audit-no-issues-found = AUDIT: ongelmia ei löytynyt.
|
||||||
.audit-reference-s-to-undefined-block-s = AUDIT: viittaus määrittelemättömiin lohkoihin: __ocs_fmt_0__
|
.audit-fix-any-errors-detected = AUDIT Korjataanko havaitut virheet? [Kyllä / Ei] <Ei>:
|
||||||
.audit-reference-s-to-undefined-layer-s = AUDIT: viittaukset määrittelemättömiin tasoihin: __ocs_fmt_0__
|
.audit-error-s-warning-s-found = AUDIT: löytyi __ocs_fmt_0__ virhettä, __ocs_fmt_1__ varoitusta.
|
||||||
.audit-report-only-no-automatic-repair-performe = AUDIT: vain raportti – automaattista korjausta ei suoritettu.
|
.audit-repair-s-applied-issue-s-left = AUDIT: __ocs_fmt_0__ korjausta tehty, __ocs_fmt_1__ ongelmaa ratkaisematta.
|
||||||
.audit-scanned-total-object-s = AUDIT: skannatut __ocs_fmt_0__-objektit.
|
.audit-scanned-total-object-s = AUDIT: skannatut __ocs_fmt_0__-objektit.
|
||||||
.above-text = Tekstin yläpuolella
|
.above-text = Tekstin yläpuolella
|
||||||
.active-dim-style-set-to-name-arg = Aktiivinen himmennystyyli asetettu "__ocs_fmt_0__"
|
.active-dim-style-set-to-name-arg = Aktiivinen himmennystyyli asetettu "__ocs_fmt_0__"
|
||||||
|
|||||||
@@ -225,9 +225,7 @@ recovery =
|
|||||||
.failed-description = La récupération n'a pas produit de données de dessin utilisables. Consultez le rapport et essayez une sauvegarde ou une copie d'enregistrement automatique.
|
.failed-description = La récupération n'a pas produit de données de dessin utilisables. Consultez le rapport et essayez une sauvegarde ou une copie d'enregistrement automatique.
|
||||||
.entities-checked = Entités vérifiées
|
.entities-checked = Entités vérifiées
|
||||||
.issues-found = Problèmes détectés
|
.issues-found = Problèmes détectés
|
||||||
.entities-removed = Entités supprimées
|
|
||||||
.references-checked = Références vérifiées
|
.references-checked = Références vérifiées
|
||||||
.referenced-entities-removed = Entités référencées supprimées
|
|
||||||
.references-unavailable = Références indisponibles
|
.references-unavailable = Références indisponibles
|
||||||
.log-path = Journal de récupération
|
.log-path = Journal de récupération
|
||||||
.log-write-failed = Impossible d'écrire le journal de récupération
|
.log-write-failed = Impossible d'écrire le journal de récupération
|
||||||
@@ -2591,8 +2589,6 @@ file =
|
|||||||
.usage-undo-number-of-steps = Utilisation : UNDO [number of steps]
|
.usage-undo-number-of-steps = Utilisation : UNDO [number of steps]
|
||||||
.used-for-the-first-save-of-a-new-drawing-exist = Utilisé pour la première sauvegarde d'un nouveau dessin. Les dessins existants conservent leur type de fichier et leur version.
|
.used-for-the-first-save-of-a-new-drawing-exist = Utilisé pour la première sauvegarde d'un nouveau dessin. Les dessins existants conservent leur type de fichier et leur version.
|
||||||
.visual-style-label = Style visuel : __ocs_fmt_0__.
|
.visual-style-label = Style visuel : __ocs_fmt_0__.
|
||||||
.warning-corrupt-entities-dropped-parser-junk-b = Avertissement : __ocs_fmt_0__ objet(s) corrompu(s) ignoré(s) (données d’analyse invalides — normales ou nombres incorrects)
|
|
||||||
.warning-corrupt-xref-entities-dropped = Avertissement : __ocs_fmt_0__ objet(s) de référence externe corrompu(s) ignoré(s)
|
|
||||||
.xref-loaded = XREF Charge "__ocs_fmt_0__"
|
.xref-loaded = XREF Charge "__ocs_fmt_0__"
|
||||||
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__ : impossible de créer le ZIP de transmission (__ocs_fmt_1__).
|
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__ : impossible de créer le ZIP de transmission (__ocs_fmt_1__).
|
||||||
.cmd-cannot-create-folder-e = __ocs_fmt_0__: ne peut pas créer de dossier (__ocs_fmt_1__).
|
.cmd-cannot-create-folder-e = __ocs_fmt_0__: ne peut pas créer de dossier (__ocs_fmt_1__).
|
||||||
@@ -5639,9 +5635,9 @@ styles =
|
|||||||
.aci-color-index = ACI Indice de couleur
|
.aci-color-index = ACI Indice de couleur
|
||||||
.aci = ACI:
|
.aci = ACI:
|
||||||
.audit-no-issues-found = AUDIT: aucun problème trouvé.
|
.audit-no-issues-found = AUDIT: aucun problème trouvé.
|
||||||
.audit-reference-s-to-undefined-block-s = AUDIT: référence(s) à un ou plusieurs blocs non définis: __ocs_fmt_0__
|
.audit-fix-any-errors-detected = AUDIT Corriger les erreurs détectées ? [Oui / Non] <Non> :
|
||||||
.audit-reference-s-to-undefined-layer-s = AUDIT : références à des calques non définis : __ocs_fmt_0__
|
.audit-error-s-warning-s-found = AUDIT : __ocs_fmt_0__ erreur(s), __ocs_fmt_1__ avertissement(s) trouvé(s).
|
||||||
.audit-report-only-no-automatic-repair-performe = AUDIT: rapport seulement — aucune réparation automatique n'est effectuée.
|
.audit-repair-s-applied-issue-s-left = AUDIT : __ocs_fmt_0__ réparation(s) appliquée(s), __ocs_fmt_1__ problème(s) non résolu(s).
|
||||||
.audit-scanned-total-object-s = AUDIT : objets analysés : __ocs_fmt_0__.
|
.audit-scanned-total-object-s = AUDIT : objets analysés : __ocs_fmt_0__.
|
||||||
.above-text = Texte ci-dessus
|
.above-text = Texte ci-dessus
|
||||||
.active-dim-style-set-to-name-arg = Style de cote courant défini sur « __ocs_fmt_0__ »
|
.active-dim-style-set-to-name-arg = Style de cote courant défini sur « __ocs_fmt_0__ »
|
||||||
|
|||||||
@@ -225,9 +225,7 @@ recovery =
|
|||||||
.failed-description = पुनर्प्राप्ति उपयोग योग्य ड्रॉइंग डेटा नहीं बना सकी। रिपोर्ट की समीक्षा करें और बैकअप या स्वतः-सहेजी गई प्रति आज़माएँ।
|
.failed-description = पुनर्प्राप्ति उपयोग योग्य ड्रॉइंग डेटा नहीं बना सकी। रिपोर्ट की समीक्षा करें और बैकअप या स्वतः-सहेजी गई प्रति आज़माएँ।
|
||||||
.entities-checked = जाँची गई एंटिटियाँ
|
.entities-checked = जाँची गई एंटिटियाँ
|
||||||
.issues-found = मिली समस्याएँ
|
.issues-found = मिली समस्याएँ
|
||||||
.entities-removed = हटाई गई एंटिटियाँ
|
|
||||||
.references-checked = जाँचे गए संदर्भ
|
.references-checked = जाँचे गए संदर्भ
|
||||||
.referenced-entities-removed = हटाई गई संदर्भित एंटिटियाँ
|
|
||||||
.references-unavailable = अनुपलब्ध संदर्भ
|
.references-unavailable = अनुपलब्ध संदर्भ
|
||||||
.log-path = पुनर्प्राप्ति लॉग
|
.log-path = पुनर्प्राप्ति लॉग
|
||||||
.log-write-failed = पुनर्प्राप्ति लॉग लिखा नहीं जा सका
|
.log-write-failed = पुनर्प्राप्ति लॉग लिखा नहीं जा सका
|
||||||
@@ -2579,8 +2577,6 @@ file =
|
|||||||
.usage-undo-number-of-steps = उपयोग: UNDO [number of steps]
|
.usage-undo-number-of-steps = उपयोग: UNDO [number of steps]
|
||||||
.used-for-the-first-save-of-a-new-drawing-exist = नई ड्रॉइंग को पहली बार सहेजते समय उपयोग होता है। मौजूदा ड्रॉइंग अपना फ़ाइल प्रकार और संस्करण बनाए रखती हैं।
|
.used-for-the-first-save-of-a-new-drawing-exist = नई ड्रॉइंग को पहली बार सहेजते समय उपयोग होता है। मौजूदा ड्रॉइंग अपना फ़ाइल प्रकार और संस्करण बनाए रखती हैं।
|
||||||
.visual-style-label = दृश्य शैली: __ocs_fmt_0__
|
.visual-style-label = दृश्य शैली: __ocs_fmt_0__
|
||||||
.warning-corrupt-entities-dropped-parser-junk-b = चेतावनी: __ocs_fmt_0__ दूषित ऑब्जेक्ट छोड़े गए (अमान्य पार्सर डेटा — गलत नॉर्मल या गिनती)
|
|
||||||
.warning-corrupt-xref-entities-dropped = चेतावनी: __ocs_fmt_0__ दूषित xref ऑब्जेक्ट छोड़े गए
|
|
||||||
.xref-loaded = XREF लोड हो गया "__ocs_fmt_0__"
|
.xref-loaded = XREF लोड हो गया "__ocs_fmt_0__"
|
||||||
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: ट्रांसमिट ZIP नहीं बनाया जा सकता (__ocs_fmt_1__)।
|
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: ट्रांसमिट ZIP नहीं बनाया जा सकता (__ocs_fmt_1__)।
|
||||||
.cmd-cannot-create-folder-e = __ocs_fmt_0__: फ़ोल्डर नहीं बना सकता (__ocs_fmt_1__).
|
.cmd-cannot-create-folder-e = __ocs_fmt_0__: फ़ोल्डर नहीं बना सकता (__ocs_fmt_1__).
|
||||||
@@ -5626,9 +5622,9 @@ styles =
|
|||||||
.aci-color-index = ACI रंग सूचकांक
|
.aci-color-index = ACI रंग सूचकांक
|
||||||
.aci = ACI:
|
.aci = ACI:
|
||||||
.audit-no-issues-found = AUDIT: कोई समस्या नहीं मिली।
|
.audit-no-issues-found = AUDIT: कोई समस्या नहीं मिली।
|
||||||
.audit-reference-s-to-undefined-block-s = AUDIT: संदर्भ (s) अपरिभाषित ब्लॉकों के लिए: __ocs_fmt_0__
|
.audit-fix-any-errors-detected = AUDIT पाई गई त्रुटियाँ ठीक करें? [हाँ / नहीं] <नहीं>:
|
||||||
.audit-reference-s-to-undefined-layer-s = AUDIT: अपरिभाषित लेयर के संदर्भ: __ocs_fmt_0__
|
.audit-error-s-warning-s-found = AUDIT: __ocs_fmt_0__ त्रुटि(याँ), __ocs_fmt_1__ चेतावनी(याँ) मिलीं।
|
||||||
.audit-report-only-no-automatic-repair-performe = AUDIT: केवल रिपोर्ट - कोई स्वचालित मरम्मत नहीं की जाती है।
|
.audit-repair-s-applied-issue-s-left = AUDIT: __ocs_fmt_0__ सुधार लागू हुए, __ocs_fmt_1__ समस्या(एँ) अनसुलझी रहीं।
|
||||||
.audit-scanned-total-object-s = AUDIT: __ocs_fmt_0__ ऑब्जेक्ट जाँचे गए।
|
.audit-scanned-total-object-s = AUDIT: __ocs_fmt_0__ ऑब्जेक्ट जाँचे गए।
|
||||||
.above-text = पाठ के ऊपर
|
.above-text = पाठ के ऊपर
|
||||||
.active-dim-style-set-to-name-arg = सक्रिय मंद शैली "__ocs_fmt_0__" के लिए सेट
|
.active-dim-style-set-to-name-arg = सक्रिय मंद शैली "__ocs_fmt_0__" के लिए सेट
|
||||||
|
|||||||
@@ -224,9 +224,7 @@ recovery =
|
|||||||
.failed-description = A helyreállítás nem eredményezett használható rajzadatokat. Tekintse át a jelentést, és próbáljon meg egy biztonsági vagy automatikusan mentett példányt.
|
.failed-description = A helyreállítás nem eredményezett használható rajzadatokat. Tekintse át a jelentést, és próbáljon meg egy biztonsági vagy automatikusan mentett példányt.
|
||||||
.entities-checked = Ellenőrzött entitások
|
.entities-checked = Ellenőrzött entitások
|
||||||
.issues-found = Talált problémák
|
.issues-found = Talált problémák
|
||||||
.entities-removed = Eltávolított entitások
|
|
||||||
.references-checked = Ellenőrzött hivatkozások
|
.references-checked = Ellenőrzött hivatkozások
|
||||||
.referenced-entities-removed = Eltávolított hivatkozott entitások
|
|
||||||
.references-unavailable = Nem elérhető hivatkozások
|
.references-unavailable = Nem elérhető hivatkozások
|
||||||
.log-path = Helyreállítási napló
|
.log-path = Helyreállítási napló
|
||||||
.log-write-failed = A helyreállítási napló nem írható
|
.log-write-failed = A helyreállítási napló nem írható
|
||||||
@@ -2590,8 +2588,6 @@ file =
|
|||||||
.usage-undo-number-of-steps = Használat: UNDO [lépések száma]
|
.usage-undo-number-of-steps = Használat: UNDO [lépések száma]
|
||||||
.used-for-the-first-save-of-a-new-drawing-exist = Egy új rajz első mentésénél használatos. A meglévő rajzok megtartják fájltípusukat és verziójukat.
|
.used-for-the-first-save-of-a-new-drawing-exist = Egy új rajz első mentésénél használatos. A meglévő rajzok megtartják fájltípusukat és verziójukat.
|
||||||
.visual-style-label = Vizuális stílus: __ocs_fmt_0__.
|
.visual-style-label = Vizuális stílus: __ocs_fmt_0__.
|
||||||
.warning-corrupt-entities-dropped-parser-junk-b = Figyelmeztetés: __ocs_fmt_0__ sérült objektum kihagyva (érvénytelen adatok: hibás normálvektorok / elemszámok)
|
|
||||||
.warning-corrupt-xref-entities-dropped = Figyelmeztetés: __ocs_fmt_0__ sérült xref-objektum kihagyva
|
|
||||||
.xref-loaded = XREF betöltve: "__ocs_fmt_0__"
|
.xref-loaded = XREF betöltve: "__ocs_fmt_0__"
|
||||||
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: nem hozható létre az átviteli ZIP (__ocs_fmt_1__).
|
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: nem hozható létre az átviteli ZIP (__ocs_fmt_1__).
|
||||||
.cmd-cannot-create-folder-e = __ocs_fmt_0__: nem hozható létre mappa (__ocs_fmt_1__).
|
.cmd-cannot-create-folder-e = __ocs_fmt_0__: nem hozható létre mappa (__ocs_fmt_1__).
|
||||||
@@ -5627,9 +5623,9 @@ styles =
|
|||||||
.aci-color-index = ACI színindex
|
.aci-color-index = ACI színindex
|
||||||
.aci = ACI:
|
.aci = ACI:
|
||||||
.audit-no-issues-found = AUDIT: nem található probléma.
|
.audit-no-issues-found = AUDIT: nem található probléma.
|
||||||
.audit-reference-s-to-undefined-block-s = AUDIT: hivatkozás(ok) meghatározatlan blokk(ok)ra: __ocs_fmt_0__
|
.audit-fix-any-errors-detected = AUDIT Javítsa az észlelt hibákat? [Igen / Nem] <Nem>:
|
||||||
.audit-reference-s-to-undefined-layer-s = AUDIT: hivatkozások nem definiált fóliákra: __ocs_fmt_0__
|
.audit-error-s-warning-s-found = AUDIT: __ocs_fmt_0__ hiba, __ocs_fmt_1__ figyelmeztetés található.
|
||||||
.audit-report-only-no-automatic-repair-performe = AUDIT: csak jelentés – nem történt automatikus javítás.
|
.audit-repair-s-applied-issue-s-left = AUDIT: __ocs_fmt_0__ javítás alkalmazva, __ocs_fmt_1__ probléma megoldatlan.
|
||||||
.audit-scanned-total-object-s = AUDIT: __ocs_fmt_0__ objektum ellenőrizve.
|
.audit-scanned-total-object-s = AUDIT: __ocs_fmt_0__ objektum ellenőrizve.
|
||||||
.above-text = A szöveg felett
|
.above-text = A szöveg felett
|
||||||
.active-dim-style-set-to-name-arg = Aktív méretezési stílus: „__ocs_fmt_0__”
|
.active-dim-style-set-to-name-arg = Aktív méretezési stílus: „__ocs_fmt_0__”
|
||||||
|
|||||||
@@ -225,9 +225,7 @@ recovery =
|
|||||||
.failed-description = Il recupero non ha prodotto dati di disegno utilizzabili. Esamina il rapporto e prova una copia di backup o di salvataggio automatico.
|
.failed-description = Il recupero non ha prodotto dati di disegno utilizzabili. Esamina il rapporto e prova una copia di backup o di salvataggio automatico.
|
||||||
.entities-checked = Entità controllate
|
.entities-checked = Entità controllate
|
||||||
.issues-found = Problemi rilevati
|
.issues-found = Problemi rilevati
|
||||||
.entities-removed = Entità rimosse
|
|
||||||
.references-checked = Riferimenti controllati
|
.references-checked = Riferimenti controllati
|
||||||
.referenced-entities-removed = Entità referenziate rimosse
|
|
||||||
.references-unavailable = Riferimenti non disponibili
|
.references-unavailable = Riferimenti non disponibili
|
||||||
.log-path = Registro di recupero
|
.log-path = Registro di recupero
|
||||||
.log-write-failed = Impossibile scrivere il registro di recupero
|
.log-write-failed = Impossibile scrivere il registro di recupero
|
||||||
@@ -2590,8 +2588,6 @@ file =
|
|||||||
.usage-undo-number-of-steps = Utilizzo: UNDO [numero di passi]
|
.usage-undo-number-of-steps = Utilizzo: UNDO [numero di passi]
|
||||||
.used-for-the-first-save-of-a-new-drawing-exist = Utilizzato per il primo salvataggio di un nuovo disegno. I disegni esistenti mantengono il tipo e la versione del file.
|
.used-for-the-first-save-of-a-new-drawing-exist = Utilizzato per il primo salvataggio di un nuovo disegno. I disegni esistenti mantengono il tipo e la versione del file.
|
||||||
.visual-style-label = Stile visivo: __ocs_fmt_0__.
|
.visual-style-label = Stile visivo: __ocs_fmt_0__.
|
||||||
.warning-corrupt-entities-dropped-parser-junk-b = Avviso: entità corrotte __ocs_fmt_0__ eliminate (spazzatura del parser: valori normali/conteggi errati)
|
|
||||||
.warning-corrupt-xref-entities-dropped = Avviso: entità xrif corrotte __ocs_fmt_0__ eliminate
|
|
||||||
.xref-loaded = XREF Caricato "__ocs_fmt_0__"
|
.xref-loaded = XREF Caricato "__ocs_fmt_0__"
|
||||||
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: impossibile creare il ZIP di trasmissione (__ocs_fmt_1__).
|
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: impossibile creare il ZIP di trasmissione (__ocs_fmt_1__).
|
||||||
.cmd-cannot-create-folder-e = __ocs_fmt_0__: impossibile creare la cartella (__ocs_fmt_1__).
|
.cmd-cannot-create-folder-e = __ocs_fmt_0__: impossibile creare la cartella (__ocs_fmt_1__).
|
||||||
@@ -5637,9 +5633,9 @@ styles =
|
|||||||
.aci-color-index = ACI Indice colori
|
.aci-color-index = ACI Indice colori
|
||||||
.aci = ACI:
|
.aci = ACI:
|
||||||
.audit-no-issues-found = AUDIT: nessun problema trovato.
|
.audit-no-issues-found = AUDIT: nessun problema trovato.
|
||||||
.audit-reference-s-to-undefined-block-s = AUDIT: riferimento/i a blocchi non definiti: __ocs_fmt_0__
|
.audit-fix-any-errors-detected = AUDIT Correggere gli errori rilevati? [Sì / No] <No>:
|
||||||
.audit-reference-s-to-undefined-layer-s = AUDIT: riferimento/i a livelli non definiti: __ocs_fmt_0__
|
.audit-error-s-warning-s-found = AUDIT: trovati __ocs_fmt_0__ errore/i, __ocs_fmt_1__ avviso/i.
|
||||||
.audit-report-only-no-automatic-repair-performe = AUDIT: solo rapporto: nessuna riparazione automatica eseguita.
|
.audit-repair-s-applied-issue-s-left = AUDIT: __ocs_fmt_0__ riparazione/i applicata/e, __ocs_fmt_1__ problema/i irrisolto/i.
|
||||||
.audit-scanned-total-object-s = AUDIT: oggetto/i __ocs_fmt_0__ scansionato/i.
|
.audit-scanned-total-object-s = AUDIT: oggetto/i __ocs_fmt_0__ scansionato/i.
|
||||||
.above-text = Sopra il testo
|
.above-text = Sopra il testo
|
||||||
.active-dim-style-set-to-name-arg = Stile di attenuazione attivo impostato su "__ocs_fmt_0__"
|
.active-dim-style-set-to-name-arg = Stile di attenuazione attivo impostato su "__ocs_fmt_0__"
|
||||||
|
|||||||
@@ -225,9 +225,7 @@ recovery =
|
|||||||
.failed-description = 修復処理で使用可能な図面データを生成できませんでした。レポートを確認し、バックアップまたは自動保存コピーをお試しください。
|
.failed-description = 修復処理で使用可能な図面データを生成できませんでした。レポートを確認し、バックアップまたは自動保存コピーをお試しください。
|
||||||
.entities-checked = 確認したエンティティ
|
.entities-checked = 確認したエンティティ
|
||||||
.issues-found = 検出した問題
|
.issues-found = 検出した問題
|
||||||
.entities-removed = 削除したエンティティ
|
|
||||||
.references-checked = 確認した参照
|
.references-checked = 確認した参照
|
||||||
.referenced-entities-removed = 削除した参照エンティティ
|
|
||||||
.references-unavailable = 使用できない参照
|
.references-unavailable = 使用できない参照
|
||||||
.log-path = 修復ログ
|
.log-path = 修復ログ
|
||||||
.log-write-failed = 修復ログを書き込めませんでした
|
.log-write-failed = 修復ログを書き込めませんでした
|
||||||
@@ -2581,8 +2579,6 @@ file =
|
|||||||
.usage-undo-number-of-steps = 使用法: UNDO [number of steps]
|
.usage-undo-number-of-steps = 使用法: UNDO [number of steps]
|
||||||
.used-for-the-first-save-of-a-new-drawing-exist = 新しい図面の初回保存時に使用されます。既存の図面ではファイル形式とバージョンが維持されます。
|
.used-for-the-first-save-of-a-new-drawing-exist = 新しい図面の初回保存時に使用されます。既存の図面ではファイル形式とバージョンが維持されます。
|
||||||
.visual-style-label = 表示スタイル: __ocs_fmt_0__。
|
.visual-style-label = 表示スタイル: __ocs_fmt_0__。
|
||||||
.warning-corrupt-entities-dropped-parser-junk-b = 警告: __ocs_fmt_0__ 個の破損した図形を除外しました(パーサーの不正データ — 法線 / 数の異常)
|
|
||||||
.warning-corrupt-xref-entities-dropped = 警告: __ocs_fmt_0__ 個の破損した外部参照図形を除外しました
|
|
||||||
.xref-loaded = XREF 「__ocs_fmt_0__」をロードしました
|
.xref-loaded = XREF 「__ocs_fmt_0__」をロードしました
|
||||||
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: 転送 ZIP を作成できません(__ocs_fmt_1__)。
|
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: 転送 ZIP を作成できません(__ocs_fmt_1__)。
|
||||||
.cmd-cannot-create-folder-e = __ocs_fmt_0__: フォルダーを作成できません(__ocs_fmt_1__)。
|
.cmd-cannot-create-folder-e = __ocs_fmt_0__: フォルダーを作成できません(__ocs_fmt_1__)。
|
||||||
@@ -5626,9 +5622,9 @@ styles =
|
|||||||
.aci-color-index = ACI カラーインデックス
|
.aci-color-index = ACI カラーインデックス
|
||||||
.aci = ACI:
|
.aci = ACI:
|
||||||
.audit-no-issues-found = AUDIT: 問題は見つかりませんでした。
|
.audit-no-issues-found = AUDIT: 問題は見つかりませんでした。
|
||||||
.audit-reference-s-to-undefined-block-s = AUDIT: 未定義ブロックへの参照: __ocs_fmt_0__
|
.audit-fix-any-errors-detected = AUDIT 検出されたエラーを修正しますか? [はい / いいえ] <いいえ>:
|
||||||
.audit-reference-s-to-undefined-layer-s = AUDIT: 未定義レイヤーへの参照: __ocs_fmt_0__
|
.audit-error-s-warning-s-found = AUDIT: エラー __ocs_fmt_0__ 件、警告 __ocs_fmt_1__ 件が見つかりました。
|
||||||
.audit-report-only-no-automatic-repair-performe = AUDIT: レポートのみ — 自動修復は行いませんでした。
|
.audit-repair-s-applied-issue-s-left = AUDIT: __ocs_fmt_0__ 件の修復を適用し、__ocs_fmt_1__ 件の問題が未解決です。
|
||||||
.audit-scanned-total-object-s = AUDIT: __ocs_fmt_0__ 個のオブジェクトを検査しました。
|
.audit-scanned-total-object-s = AUDIT: __ocs_fmt_0__ 個のオブジェクトを検査しました。
|
||||||
.above-text = 文字の上
|
.above-text = 文字の上
|
||||||
.active-dim-style-set-to-name-arg = 現在の寸法スタイルを "__ocs_fmt_0__" に設定しました
|
.active-dim-style-set-to-name-arg = 現在の寸法スタイルを "__ocs_fmt_0__" に設定しました
|
||||||
|
|||||||
@@ -225,9 +225,7 @@ recovery =
|
|||||||
.failed-description = 복구 과정에서 사용 가능한 도면 데이터를 만들지 못했습니다. 보고서를 검토하고 백업 또는 자동 저장 사본을 사용해 보세요.
|
.failed-description = 복구 과정에서 사용 가능한 도면 데이터를 만들지 못했습니다. 보고서를 검토하고 백업 또는 자동 저장 사본을 사용해 보세요.
|
||||||
.entities-checked = 검사한 엔티티
|
.entities-checked = 검사한 엔티티
|
||||||
.issues-found = 발견된 문제
|
.issues-found = 발견된 문제
|
||||||
.entities-removed = 제거된 엔티티
|
|
||||||
.references-checked = 검사한 참조
|
.references-checked = 검사한 참조
|
||||||
.referenced-entities-removed = 제거된 참조 엔티티
|
|
||||||
.references-unavailable = 사용할 수 없는 참조
|
.references-unavailable = 사용할 수 없는 참조
|
||||||
.log-path = 복구 로그
|
.log-path = 복구 로그
|
||||||
.log-write-failed = 복구 로그를 쓸 수 없습니다
|
.log-write-failed = 복구 로그를 쓸 수 없습니다
|
||||||
@@ -2590,8 +2588,6 @@ file =
|
|||||||
.usage-undo-number-of-steps = 사용법: UNDO [단계 수]
|
.usage-undo-number-of-steps = 사용법: UNDO [단계 수]
|
||||||
.used-for-the-first-save-of-a-new-drawing-exist = 새 도면을 처음 저장할 때 사용됩니다. 기존 도면은 파일 유형과 버전을 유지합니다.
|
.used-for-the-first-save-of-a-new-drawing-exist = 새 도면을 처음 저장할 때 사용됩니다. 기존 도면은 파일 유형과 버전을 유지합니다.
|
||||||
.visual-style-label = 시각적 스타일: __ocs_fmt_0__.
|
.visual-style-label = 시각적 스타일: __ocs_fmt_0__.
|
||||||
.warning-corrupt-entities-dropped-parser-junk-b = 경고: __ocs_fmt_0__ 손상된 엔터티가 삭제됨(파서 정크 - 잘못된 노멀/카운트)
|
|
||||||
.warning-corrupt-xref-entities-dropped = 경고: __ocs_fmt_0__ 손상된 외부 참조 엔티티가 삭제되었습니다.
|
|
||||||
.xref-loaded = XREF가 "__ocs_fmt_0__"를 로드했습니다.
|
.xref-loaded = XREF가 "__ocs_fmt_0__"를 로드했습니다.
|
||||||
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: 전송 ZIP을 만들 수 없습니다(__ocs_fmt_1__).
|
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: 전송 ZIP을 만들 수 없습니다(__ocs_fmt_1__).
|
||||||
.cmd-cannot-create-folder-e = __ocs_fmt_0__: 폴더(__ocs_fmt_1__)를 생성할 수 없습니다.
|
.cmd-cannot-create-folder-e = __ocs_fmt_0__: 폴더(__ocs_fmt_1__)를 생성할 수 없습니다.
|
||||||
@@ -5637,9 +5633,9 @@ styles =
|
|||||||
.aci-color-index = ACI 컬러 인덱스
|
.aci-color-index = ACI 컬러 인덱스
|
||||||
.aci = ACI:
|
.aci = ACI:
|
||||||
.audit-no-issues-found = AUDIT: 문제가 발견되지 않았습니다.
|
.audit-no-issues-found = AUDIT: 문제가 발견되지 않았습니다.
|
||||||
.audit-reference-s-to-undefined-block-s = AUDIT: 정의되지 않은 블록에 대한 참조: __ocs_fmt_0__
|
.audit-fix-any-errors-detected = AUDIT 감지된 오류를 수정하시겠습니까? [예 / 아니요] <아니요>:
|
||||||
.audit-reference-s-to-undefined-layer-s = AUDIT: 정의되지 않은 레이어에 대한 참조: __ocs_fmt_0__
|
.audit-error-s-warning-s-found = AUDIT: 오류 __ocs_fmt_0__개, 경고 __ocs_fmt_1__개를 찾았습니다.
|
||||||
.audit-report-only-no-automatic-repair-performe = AUDIT: 보고 전용 - 자동 복구가 수행되지 않습니다.
|
.audit-repair-s-applied-issue-s-left = AUDIT: 복구 __ocs_fmt_0__개 적용, 미해결 문제 __ocs_fmt_1__개.
|
||||||
.audit-scanned-total-object-s = AUDIT: __ocs_fmt_0__ 개체를 스캔했습니다.
|
.audit-scanned-total-object-s = AUDIT: __ocs_fmt_0__ 개체를 스캔했습니다.
|
||||||
.above-text = 텍스트 위
|
.above-text = 텍스트 위
|
||||||
.active-dim-style-set-to-name-arg = 활성 밝기 스타일이 "__ocs_fmt_0__"로 설정됨
|
.active-dim-style-set-to-name-arg = 활성 밝기 스타일이 "__ocs_fmt_0__"로 설정됨
|
||||||
|
|||||||
@@ -224,9 +224,7 @@ recovery =
|
|||||||
.failed-description = ການກູ້ຄືນບໍ່ສາມາດສ້າງຂໍ້ມູນຮູບແຕ້ມທີ່ໃຊ້ງານໄດ້. ກະລຸນາກວດສອບລາຍງານ ແລະ ລອງໃຊ້ສຳເນົາສຳຮອງ ຫຼື ໄຟລ໌ບັນທຶກອັດຕະໂນມັດ.
|
.failed-description = ການກູ້ຄືນບໍ່ສາມາດສ້າງຂໍ້ມູນຮູບແຕ້ມທີ່ໃຊ້ງານໄດ້. ກະລຸນາກວດສອບລາຍງານ ແລະ ລອງໃຊ້ສຳເນົາສຳຮອງ ຫຼື ໄຟລ໌ບັນທຶກອັດຕະໂນມັດ.
|
||||||
.entities-checked = ອົງປະກອບທີ່ກວດສອບແລ້ວ
|
.entities-checked = ອົງປະກອບທີ່ກວດສອບແລ້ວ
|
||||||
.issues-found = ບັນຫາທີ່ພົບ
|
.issues-found = ບັນຫາທີ່ພົບ
|
||||||
.entities-removed = ອົງປະກອບທີ່ຖືກລຶບອອກ
|
|
||||||
.references-checked = ຈຸດອ້າງອີງທີ່ກວດສອບແລ້ວ
|
.references-checked = ຈຸດອ້າງອີງທີ່ກວດສອບແລ້ວ
|
||||||
.referenced-entities-removed = ອົງປະກອບອ້າງອີງທີ່ຖືກລຶບອອກ
|
|
||||||
.references-unavailable = ຈຸດອ້າງອີງບໍ່ພ້ອມໃຊ້ງານ
|
.references-unavailable = ຈຸດອ້າງອີງບໍ່ພ້ອມໃຊ້ງານ
|
||||||
.log-path = ບັນທຶກເຫດການການກູ້ຄືນ
|
.log-path = ບັນທຶກເຫດການການກູ້ຄືນ
|
||||||
.log-write-failed = ບໍ່ສາມາດຂຽນບັນທຶກເຫດການການກູ້ຄືນໄດ້
|
.log-write-failed = ບໍ່ສາມາດຂຽນບັນທຶກເຫດການການກູ້ຄືນໄດ້
|
||||||
@@ -2598,8 +2596,6 @@ file =
|
|||||||
.usage-undo-number-of-steps = ວິທີໃຊ້: UNDO [ຈຳນວນຂັ້ນຕອນ]
|
.usage-undo-number-of-steps = ວິທີໃຊ້: UNDO [ຈຳນວນຂັ້ນຕອນ]
|
||||||
.used-for-the-first-save-of-a-new-drawing-exist = ໃຊ້ສຳລັບການບັນທຶກຄັ້ງທຳອິດຂອງແບບແຕ້ມໃໝ່. ແບບແຕ້ມທີ່ມີຢູ່ແລ້ວຈະຮັກສາປະເພດໄຟລ໌ ແລະ ເວີຊັນເດີມໄວ້.
|
.used-for-the-first-save-of-a-new-drawing-exist = ໃຊ້ສຳລັບການບັນທຶກຄັ້ງທຳອິດຂອງແບບແຕ້ມໃໝ່. ແບບແຕ້ມທີ່ມີຢູ່ແລ້ວຈະຮັກສາປະເພດໄຟລ໌ ແລະ ເວີຊັນເດີມໄວ້.
|
||||||
.visual-style-label = ຮູບແບບມຸມມອງ: __ocs_fmt_0__.
|
.visual-style-label = ຮູບແບບມຸມມອງ: __ocs_fmt_0__.
|
||||||
.warning-corrupt-entities-dropped-parser-junk-b = ຄຳເຕືອນ: ຕັດອົງປະກອບທີ່ເສຍຫາຍຖິ້ມ __ocs_fmt_0__ ອັນ (ຂໍ້ມູນເສດຈາກການວິເຄາະ — ຄ່າແນວຕັ້ງສາກ/ຈຳນວນຜິດພາດ)
|
|
||||||
.warning-corrupt-xref-entities-dropped = ຄຳເຕືອນ: ຕັດອົງປະກອບ xref ທີ່ເສຍຫາຍຖິ້ມ __ocs_fmt_0__ ອັນ
|
|
||||||
.xref-loaded = XREF ໂຫຼດແລ້ວ "__ocs_fmt_0__"
|
.xref-loaded = XREF ໂຫຼດແລ້ວ "__ocs_fmt_0__"
|
||||||
.cmd-cannot-create-folder-e = __ocs_fmt_0__: ບໍ່ສາມາດສ້າງໂຟລເດີໄດ້ (__ocs_fmt_1__).
|
.cmd-cannot-create-folder-e = __ocs_fmt_0__: ບໍ່ສາມາດສ້າງໂຟລເດີໄດ້ (__ocs_fmt_1__).
|
||||||
.cmd-packaged-copied-file-s-into = __ocs_fmt_0__: ລວມໄຟລ໌ ແລະ ສຳເນົາ __ocs_fmt_1__ ໄຟລ໌ ລົງໃນ __ocs_fmt_2__
|
.cmd-packaged-copied-file-s-into = __ocs_fmt_0__: ລວມໄຟລ໌ ແລະ ສຳເນົາ __ocs_fmt_1__ ໄຟລ໌ ລົງໃນ __ocs_fmt_2__
|
||||||
@@ -5638,9 +5634,9 @@ styles =
|
|||||||
.aci-color-index = ດັດຊະນີສີ ACI
|
.aci-color-index = ດັດຊະນີສີ ACI
|
||||||
.aci = ACI:
|
.aci = ACI:
|
||||||
.audit-no-issues-found = AUDIT: ບໍ່ພົບຂໍ້ຜິດພາດ.
|
.audit-no-issues-found = AUDIT: ບໍ່ພົບຂໍ້ຜິດພາດ.
|
||||||
.audit-reference-s-to-undefined-block-s = AUDIT: ການອ້າງອີງເຖິງບລັອກທີ່ບໍ່ໄດ້ກຳນົດ: __ocs_fmt_0__
|
.audit-fix-any-errors-detected = AUDIT ແກ້ໄຂຂໍ້ຜິດພາດທີ່ກວດພົບບໍ? [ແມ່ນ / ບໍ່] <ບໍ່>:
|
||||||
.audit-reference-s-to-undefined-layer-s = AUDIT: ການອ້າງອີງເຖິງເລເຢີທີ່ບໍ່ໄດ້ກຳນົດ: __ocs_fmt_0__
|
.audit-error-s-warning-s-found = AUDIT: ພົບຂໍ້ຜິດພາດ __ocs_fmt_0__ ລາຍການ, ຄຳເຕືອນ __ocs_fmt_1__ ລາຍການ.
|
||||||
.audit-report-only-no-automatic-repair-performe = AUDIT: ລາຍງານເທົ່ານັ້ນ — ບໍ່ໄດ້ມີການສ້ອມແປງອັດຕະໂນມັດ.
|
.audit-repair-s-applied-issue-s-left = AUDIT: ສ້ອມແປງແລ້ວ __ocs_fmt_0__ ລາຍການ, ບັນຫາທີ່ຍັງບໍ່ໄດ້ແກ້ __ocs_fmt_1__ ລາຍການ.
|
||||||
.audit-scanned-total-object-s = AUDIT: ສະແກນທັງໝົດ __ocs_fmt_0__ ວັດຖຸ.
|
.audit-scanned-total-object-s = AUDIT: ສະແກນທັງໝົດ __ocs_fmt_0__ ວັດຖຸ.
|
||||||
.above-text = ເທິງຂໍ້ຄວາມ
|
.above-text = ເທິງຂໍ້ຄວາມ
|
||||||
.active-dim-style-set-to-name-arg = ຮູບແບບຂະໜາດທີ່ໃຊ້ງານຕັ້ງເປັນ "__ocs_fmt_0__"
|
.active-dim-style-set-to-name-arg = ຮູບແບບຂະໜາດທີ່ໃຊ້ງານຕັ້ງເປັນ "__ocs_fmt_0__"
|
||||||
|
|||||||
@@ -225,9 +225,7 @@ recovery =
|
|||||||
.failed-description = Het herstel kon geen bruikbare tekeninggegevens opleveren. Controleer het rapport en probeer een reservekopie of automatisch opgeslagen kopie.
|
.failed-description = Het herstel kon geen bruikbare tekeninggegevens opleveren. Controleer het rapport en probeer een reservekopie of automatisch opgeslagen kopie.
|
||||||
.entities-checked = Gecontroleerde objecten
|
.entities-checked = Gecontroleerde objecten
|
||||||
.issues-found = Gevonden problemen
|
.issues-found = Gevonden problemen
|
||||||
.entities-removed = Verwijderde objecten
|
|
||||||
.references-checked = Gecontroleerde verwijzingen
|
.references-checked = Gecontroleerde verwijzingen
|
||||||
.referenced-entities-removed = Verwijderde objecten waarnaar werd verwezen
|
|
||||||
.references-unavailable = Niet-beschikbare verwijzingen
|
.references-unavailable = Niet-beschikbare verwijzingen
|
||||||
.log-path = Herstellogboek
|
.log-path = Herstellogboek
|
||||||
.log-write-failed = Het herstellogboek kon niet worden geschreven
|
.log-write-failed = Het herstellogboek kon niet worden geschreven
|
||||||
@@ -2591,8 +2589,6 @@ file =
|
|||||||
.usage-undo-number-of-steps = Gebruik: UNDO [number of steps]
|
.usage-undo-number-of-steps = Gebruik: UNDO [number of steps]
|
||||||
.used-for-the-first-save-of-a-new-drawing-exist = Gebruikt voor de eerste opslag van een nieuwe tekening. Bestaande tekeningen houden hun bestandstype en versie.
|
.used-for-the-first-save-of-a-new-drawing-exist = Gebruikt voor de eerste opslag van een nieuwe tekening. Bestaande tekeningen houden hun bestandstype en versie.
|
||||||
.visual-style-label = Visuele stijl: __ocs_fmt_0__.
|
.visual-style-label = Visuele stijl: __ocs_fmt_0__.
|
||||||
.warning-corrupt-entities-dropped-parser-junk-b = Waarschuwing: __ocs_fmt_0__ beschadigde objecten overgeslagen (ongeldige parsergegevens — foutieve normalen of aantallen)
|
|
||||||
.warning-corrupt-xref-entities-dropped = Waarschuwing: __ocs_fmt_0__ beschadigde xref-objecten overgeslagen
|
|
||||||
.xref-loaded = XREF geladen "__ocs_fmt_0__"
|
.xref-loaded = XREF geladen "__ocs_fmt_0__"
|
||||||
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: kan de transmissie-ZIP niet maken (__ocs_fmt_1__).
|
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: kan de transmissie-ZIP niet maken (__ocs_fmt_1__).
|
||||||
.cmd-cannot-create-folder-e = __ocs_fmt_0__: kan map (__ocs_fmt_1__) niet aanmaken.
|
.cmd-cannot-create-folder-e = __ocs_fmt_0__: kan map (__ocs_fmt_1__) niet aanmaken.
|
||||||
@@ -5636,9 +5632,9 @@ styles =
|
|||||||
.aci-color-index = ACI Kleurindex
|
.aci-color-index = ACI Kleurindex
|
||||||
.aci = ACI:
|
.aci = ACI:
|
||||||
.audit-no-issues-found = AUDIT: geen problemen gevonden.
|
.audit-no-issues-found = AUDIT: geen problemen gevonden.
|
||||||
.audit-reference-s-to-undefined-block-s = AUDIT: verwijzing(s) naar ongedefinieerd symbool(en): __ocs_fmt_0__
|
.audit-fix-any-errors-detected = AUDIT Gevonden fouten herstellen? [Ja / Nee] <Nee>:
|
||||||
.audit-reference-s-to-undefined-layer-s = AUDIT: verwijzing(s) naar ongedefinieerde laag(en): __ocs_fmt_0__
|
.audit-error-s-warning-s-found = AUDIT: __ocs_fmt_0__ fout(en), __ocs_fmt_1__ waarschuwing(en) gevonden.
|
||||||
.audit-report-only-no-automatic-repair-performe = AUDIT: alleen melden
|
.audit-repair-s-applied-issue-s-left = AUDIT: __ocs_fmt_0__ herstelling(en) toegepast, __ocs_fmt_1__ probleem/problemen onopgelost.
|
||||||
.audit-scanned-total-object-s = AUDIT: __ocs_fmt_0__ object(en) gecontroleerd.
|
.audit-scanned-total-object-s = AUDIT: __ocs_fmt_0__ object(en) gecontroleerd.
|
||||||
.above-text = Bovenstaande tekst
|
.above-text = Bovenstaande tekst
|
||||||
.active-dim-style-set-to-name-arg = Actieve maatstijl ingesteld op "__ocs_fmt_0__"
|
.active-dim-style-set-to-name-arg = Actieve maatstijl ingesteld op "__ocs_fmt_0__"
|
||||||
|
|||||||
@@ -225,9 +225,7 @@ recovery =
|
|||||||
.failed-description = Odzyskiwanie nie przyniosło użytecznych danych rysunku. Przejrzyj raport i spróbuj użyć kopii zapasowej lub automatycznie zapisanej.
|
.failed-description = Odzyskiwanie nie przyniosło użytecznych danych rysunku. Przejrzyj raport i spróbuj użyć kopii zapasowej lub automatycznie zapisanej.
|
||||||
.entities-checked = Sprawdzone elementy
|
.entities-checked = Sprawdzone elementy
|
||||||
.issues-found = Znalezione problemy
|
.issues-found = Znalezione problemy
|
||||||
.entities-removed = Usunięte elementy
|
|
||||||
.references-checked = Sprawdzone odnośniki
|
.references-checked = Sprawdzone odnośniki
|
||||||
.referenced-entities-removed = Usunięte elementy przywoływane
|
|
||||||
.references-unavailable = Niedostępne odnośniki
|
.references-unavailable = Niedostępne odnośniki
|
||||||
.log-path = Dziennik odzyskiwania
|
.log-path = Dziennik odzyskiwania
|
||||||
.log-write-failed = Nie można zapisać dziennika odzyskiwania
|
.log-write-failed = Nie można zapisać dziennika odzyskiwania
|
||||||
@@ -2590,8 +2588,6 @@ file =
|
|||||||
.usage-undo-number-of-steps = Sposób użycia: UNDO [liczba kroków]
|
.usage-undo-number-of-steps = Sposób użycia: UNDO [liczba kroków]
|
||||||
.used-for-the-first-save-of-a-new-drawing-exist = Używane przy pierwszym zapisie nowego rysunku. Istniejące rysunki zachowują swój typ pliku i wersję.
|
.used-for-the-first-save-of-a-new-drawing-exist = Używane przy pierwszym zapisie nowego rysunku. Istniejące rysunki zachowują swój typ pliku i wersję.
|
||||||
.visual-style-label = Styl wizualny: __ocs_fmt_0__.
|
.visual-style-label = Styl wizualny: __ocs_fmt_0__.
|
||||||
.warning-corrupt-entities-dropped-parser-junk-b = Ostrzeżenie: usunięte zostały uszkodzone jednostki __ocs_fmt_0__ (śmieci parsera — złe wartości normalne/liczby)
|
|
||||||
.warning-corrupt-xref-entities-dropped = Ostrzeżenie: usunięte zostały uszkodzone elementy odnośników zewnętrznych __ocs_fmt_0__
|
|
||||||
.xref-loaded = XREF Załadowano „__ocs_fmt_0__”
|
.xref-loaded = XREF Załadowano „__ocs_fmt_0__”
|
||||||
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: nie można utworzyć archiwum ZIP transmittalu (__ocs_fmt_1__).
|
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: nie można utworzyć archiwum ZIP transmittalu (__ocs_fmt_1__).
|
||||||
.cmd-cannot-create-folder-e = __ocs_fmt_0__: nie można utworzyć folderu (__ocs_fmt_1__).
|
.cmd-cannot-create-folder-e = __ocs_fmt_0__: nie można utworzyć folderu (__ocs_fmt_1__).
|
||||||
@@ -5637,9 +5633,9 @@ styles =
|
|||||||
.aci-color-index = Indeks kolorów ACI
|
.aci-color-index = Indeks kolorów ACI
|
||||||
.aci = ACI:
|
.aci = ACI:
|
||||||
.audit-no-issues-found = AUDIT: nie znaleziono żadnych problemów.
|
.audit-no-issues-found = AUDIT: nie znaleziono żadnych problemów.
|
||||||
.audit-reference-s-to-undefined-block-s = AUDIT: odniesienia do niezdefiniowanych bloków: __ocs_fmt_0__
|
.audit-fix-any-errors-detected = AUDIT Naprawić wykryte błędy? [Tak / Nie] <Nie>:
|
||||||
.audit-reference-s-to-undefined-layer-s = AUDIT: odniesienia do niezdefiniowanych warstw: __ocs_fmt_0__
|
.audit-error-s-warning-s-found = AUDIT: znaleziono błędy: __ocs_fmt_0__, ostrzeżenia: __ocs_fmt_1__.
|
||||||
.audit-report-only-no-automatic-repair-performe = AUDIT: tylko raport — nie wykonano automatycznej naprawy.
|
.audit-repair-s-applied-issue-s-left = AUDIT: zastosowane naprawy: __ocs_fmt_0__, nierozwiązane problemy: __ocs_fmt_1__.
|
||||||
.audit-scanned-total-object-s = AUDIT: zeskanowane obiekty __ocs_fmt_0__.
|
.audit-scanned-total-object-s = AUDIT: zeskanowane obiekty __ocs_fmt_0__.
|
||||||
.above-text = Powyżej tekstu
|
.above-text = Powyżej tekstu
|
||||||
.active-dim-style-set-to-name-arg = Aktywny styl przyciemnienia ustawiony na „__ocs_fmt_0__”
|
.active-dim-style-set-to-name-arg = Aktywny styl przyciemnienia ustawiony na „__ocs_fmt_0__”
|
||||||
|
|||||||
@@ -225,9 +225,7 @@ recovery =
|
|||||||
.failed-description = A recuperação não conseguiu produzir dados de desenho utilizáveis. Revise o relatório e tente um backup ou uma cópia de salvamento automático.
|
.failed-description = A recuperação não conseguiu produzir dados de desenho utilizáveis. Revise o relatório e tente um backup ou uma cópia de salvamento automático.
|
||||||
.entities-checked = Entidades verificadas
|
.entities-checked = Entidades verificadas
|
||||||
.issues-found = Problemas encontrados
|
.issues-found = Problemas encontrados
|
||||||
.entities-removed = Entidades removidas
|
|
||||||
.references-checked = Referências verificadas
|
.references-checked = Referências verificadas
|
||||||
.referenced-entities-removed = Entidades referenciadas removidas
|
|
||||||
.references-unavailable = Referências indisponíveis
|
.references-unavailable = Referências indisponíveis
|
||||||
.log-path = Log de recuperação
|
.log-path = Log de recuperação
|
||||||
.log-write-failed = Não foi possível gravar o log de recuperação
|
.log-write-failed = Não foi possível gravar o log de recuperação
|
||||||
@@ -2591,8 +2589,6 @@ file =
|
|||||||
.usage-undo-number-of-steps = Uso: UNDO [número de etapas]
|
.usage-undo-number-of-steps = Uso: UNDO [número de etapas]
|
||||||
.used-for-the-first-save-of-a-new-drawing-exist = Usado no primeiro salvamento de um novo desenho. Desenhos existentes mantêm seu tipo e versão de arquivo.
|
.used-for-the-first-save-of-a-new-drawing-exist = Usado no primeiro salvamento de um novo desenho. Desenhos existentes mantêm seu tipo e versão de arquivo.
|
||||||
.visual-style-label = Estilo visual: __ocs_fmt_0__.
|
.visual-style-label = Estilo visual: __ocs_fmt_0__.
|
||||||
.warning-corrupt-entities-dropped-parser-junk-b = Aviso: __ocs_fmt_0__ entidades corrompidas descartadas (dados inválidos do analisador — normais/contagens incorretas)
|
|
||||||
.warning-corrupt-xref-entities-dropped = Aviso: __ocs_fmt_0__ entidades de referência externa corrompidas descartadas
|
|
||||||
.xref-loaded = XREF “__ocs_fmt_0__” carregada
|
.xref-loaded = XREF “__ocs_fmt_0__” carregada
|
||||||
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: não foi possível criar o ZIP de transmissão (__ocs_fmt_1__).
|
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: não foi possível criar o ZIP de transmissão (__ocs_fmt_1__).
|
||||||
.cmd-cannot-create-folder-e = __ocs_fmt_0__: não é possível criar a pasta (__ocs_fmt_1__).
|
.cmd-cannot-create-folder-e = __ocs_fmt_0__: não é possível criar a pasta (__ocs_fmt_1__).
|
||||||
@@ -5638,9 +5634,9 @@ styles =
|
|||||||
.aci-color-index = Índice de cor ACI
|
.aci-color-index = Índice de cor ACI
|
||||||
.aci = ACI:
|
.aci = ACI:
|
||||||
.audit-no-issues-found = AUDIT: nenhum problema encontrado.
|
.audit-no-issues-found = AUDIT: nenhum problema encontrado.
|
||||||
.audit-reference-s-to-undefined-block-s = AUDIT: referências a blocos indefinidos: __ocs_fmt_0__
|
.audit-fix-any-errors-detected = AUDIT Corrigir os erros detectados? [Sim / Não] <Não>:
|
||||||
.audit-reference-s-to-undefined-layer-s = AUDIT: referências a camadas indefinidas: __ocs_fmt_0__
|
.audit-error-s-warning-s-found = AUDIT: __ocs_fmt_0__ erro(s), __ocs_fmt_1__ aviso(s) encontrado(s).
|
||||||
.audit-report-only-no-automatic-repair-performe = AUDIT: somente relatório — nenhum reparo automático realizado.
|
.audit-repair-s-applied-issue-s-left = AUDIT: __ocs_fmt_0__ reparo(s) aplicado(s), __ocs_fmt_1__ problema(s) não resolvido(s).
|
||||||
.audit-scanned-total-object-s = AUDIT: __ocs_fmt_0__ objetos verificados.
|
.audit-scanned-total-object-s = AUDIT: __ocs_fmt_0__ objetos verificados.
|
||||||
.above-text = Acima do texto
|
.above-text = Acima do texto
|
||||||
.active-dim-style-set-to-name-arg = Estilo de cota ativo definido como “__ocs_fmt_0__”
|
.active-dim-style-set-to-name-arg = Estilo de cota ativo definido como “__ocs_fmt_0__”
|
||||||
|
|||||||
@@ -225,9 +225,7 @@ recovery =
|
|||||||
.failed-description = Восстановить пригодные данные чертежа не удалось. Просмотрите отчёт и попробуйте резервную или автоматически сохранённую копию.
|
.failed-description = Восстановить пригодные данные чертежа не удалось. Просмотрите отчёт и попробуйте резервную или автоматически сохранённую копию.
|
||||||
.entities-checked = Проверено объектов
|
.entities-checked = Проверено объектов
|
||||||
.issues-found = Обнаружено проблем
|
.issues-found = Обнаружено проблем
|
||||||
.entities-removed = Удалено объектов
|
|
||||||
.references-checked = Проверено ссылок
|
.references-checked = Проверено ссылок
|
||||||
.referenced-entities-removed = Удалено ссылочных объектов
|
|
||||||
.references-unavailable = Недоступные ссылки
|
.references-unavailable = Недоступные ссылки
|
||||||
.log-path = Журнал восстановления
|
.log-path = Журнал восстановления
|
||||||
.log-write-failed = Не удалось записать журнал восстановления
|
.log-write-failed = Не удалось записать журнал восстановления
|
||||||
@@ -2594,8 +2592,6 @@ file =
|
|||||||
.usage-undo-number-of-steps = Использование: UNDO [number of steps]
|
.usage-undo-number-of-steps = Использование: UNDO [number of steps]
|
||||||
.used-for-the-first-save-of-a-new-drawing-exist = Используется при первом сохранении нового чертежа. Существующие чертежи сохраняют свой тип и версию файла.
|
.used-for-the-first-save-of-a-new-drawing-exist = Используется при первом сохранении нового чертежа. Существующие чертежи сохраняют свой тип и версию файла.
|
||||||
.visual-style-label = Визуальный стиль: __ocs_fmt_0__.
|
.visual-style-label = Визуальный стиль: __ocs_fmt_0__.
|
||||||
.warning-corrupt-entities-dropped-parser-junk-b = Предупреждение: повреждённые объекты пропущены: __ocs_fmt_0__ (ошибочные данные анализатора — неверные нормали или количества)
|
|
||||||
.warning-corrupt-xref-entities-dropped = Предупреждение: повреждённые объекты внешней ссылки пропущены: __ocs_fmt_0__
|
|
||||||
.xref-loaded = XREF Загруженный "__ocs_fmt_0__"
|
.xref-loaded = XREF Загруженный "__ocs_fmt_0__"
|
||||||
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: не удалось создать ZIP-пакет передачи (__ocs_fmt_1__).
|
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: не удалось создать ZIP-пакет передачи (__ocs_fmt_1__).
|
||||||
.cmd-cannot-create-folder-e = __ocs_fmt_0__: не может создавать папку (__ocs_fmt_1__).
|
.cmd-cannot-create-folder-e = __ocs_fmt_0__: не может создавать папку (__ocs_fmt_1__).
|
||||||
@@ -5639,9 +5635,9 @@ styles =
|
|||||||
.aci-color-index = Индекс цвета ACI
|
.aci-color-index = Индекс цвета ACI
|
||||||
.aci = ACI:
|
.aci = ACI:
|
||||||
.audit-no-issues-found = AUDIT: не найдено никаких проблем.
|
.audit-no-issues-found = AUDIT: не найдено никаких проблем.
|
||||||
.audit-reference-s-to-undefined-block-s = AUDIT: ссылка(ы) на неопределенный(ые) блок(ы): __ocs_fmt_0__
|
.audit-fix-any-errors-detected = AUDIT Исправить обнаруженные ошибки? [Да / Нет] <Нет>:
|
||||||
.audit-reference-s-to-undefined-layer-s = AUDIT: ссылка(ы) на неопределенный(ые) слой(ы): __ocs_fmt_0__
|
.audit-error-s-warning-s-found = AUDIT: найдено ошибок: __ocs_fmt_0__, предупреждений: __ocs_fmt_1__.
|
||||||
.audit-report-only-no-automatic-repair-performe = AUDIT: только отчет - не выполняется автоматический ремонт.
|
.audit-repair-s-applied-issue-s-left = AUDIT: применено исправлений: __ocs_fmt_0__, не устранено проблем: __ocs_fmt_1__.
|
||||||
.audit-scanned-total-object-s = AUDIT: сканируемый объект (объекты) __ocs_fmt_0__.
|
.audit-scanned-total-object-s = AUDIT: сканируемый объект (объекты) __ocs_fmt_0__.
|
||||||
.above-text = Выше текста
|
.above-text = Выше текста
|
||||||
.active-dim-style-set-to-name-arg = Активным стилем размеров назначен «__ocs_fmt_0__»
|
.active-dim-style-set-to-name-arg = Активным стилем размеров назначен «__ocs_fmt_0__»
|
||||||
|
|||||||
@@ -222,9 +222,7 @@ recovery =
|
|||||||
.failed-description = Kurtarma işlemi kullanılabilir çizim verisi üretemedi. Raporu inceleyip bir yedek veya otomatik kayıt kopyasını deneyin.
|
.failed-description = Kurtarma işlemi kullanılabilir çizim verisi üretemedi. Raporu inceleyip bir yedek veya otomatik kayıt kopyasını deneyin.
|
||||||
.entities-checked = Denetlenen obje
|
.entities-checked = Denetlenen obje
|
||||||
.issues-found = Bulunan sorun
|
.issues-found = Bulunan sorun
|
||||||
.entities-removed = Kaldırılan obje
|
|
||||||
.references-checked = Denetlenen referans
|
.references-checked = Denetlenen referans
|
||||||
.referenced-entities-removed = Referanslardan kaldırılan obje
|
|
||||||
.references-unavailable = Kullanılamayan referans
|
.references-unavailable = Kullanılamayan referans
|
||||||
.log-path = Kurtarma günlüğü
|
.log-path = Kurtarma günlüğü
|
||||||
.log-write-failed = Kurtarma günlüğü yazılamadı
|
.log-write-failed = Kurtarma günlüğü yazılamadı
|
||||||
@@ -2574,8 +2572,6 @@ file =
|
|||||||
.usage-undo-number-of-steps = Kullanım: UNDO [number of steps]
|
.usage-undo-number-of-steps = Kullanım: UNDO [number of steps]
|
||||||
.used-for-the-first-save-of-a-new-drawing-exist = Yeni bir çizimin ilk kaydında kullanılır. Mevcut çizimler dosya türünü ve sürümünü korur.
|
.used-for-the-first-save-of-a-new-drawing-exist = Yeni bir çizimin ilk kaydında kullanılır. Mevcut çizimler dosya türünü ve sürümünü korur.
|
||||||
.visual-style-label = Görsel stil: __ocs_fmt_0__.
|
.visual-style-label = Görsel stil: __ocs_fmt_0__.
|
||||||
.warning-corrupt-entities-dropped-parser-junk-b = Uyarı: __ocs_fmt_0__ bozuk nesne atıldı (ayrıştırıcı artığı — hatalı normaller / sayılar)
|
|
||||||
.warning-corrupt-xref-entities-dropped = Uyarı: __ocs_fmt_0__ bozuk dış referans nesnesi atıldı
|
|
||||||
.xref-loaded = XREF "__ocs_fmt_0__" yüklendi
|
.xref-loaded = XREF "__ocs_fmt_0__" yüklendi
|
||||||
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: aktarım ZIP'i oluşturulamıyor (__ocs_fmt_1__).
|
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: aktarım ZIP'i oluşturulamıyor (__ocs_fmt_1__).
|
||||||
.cmd-cannot-create-folder-e = __ocs_fmt_0__: Klasör oluşturulamıyor (__ocs_fmt_1__).
|
.cmd-cannot-create-folder-e = __ocs_fmt_0__: Klasör oluşturulamıyor (__ocs_fmt_1__).
|
||||||
@@ -5576,9 +5572,9 @@ styles =
|
|||||||
.aci-color-index = ACI renk dizini
|
.aci-color-index = ACI renk dizini
|
||||||
.aci = ACI:
|
.aci = ACI:
|
||||||
.audit-no-issues-found = AUDIT: sorun bulunamadı.
|
.audit-no-issues-found = AUDIT: sorun bulunamadı.
|
||||||
.audit-reference-s-to-undefined-block-s = AUDIT: tanımsız bloklara başvurular: __ocs_fmt_0__
|
.audit-fix-any-errors-detected = AUDIT Bulunan hatalar düzeltilsin mi? [Evet / Hayır] <Hayır>:
|
||||||
.audit-reference-s-to-undefined-layer-s = AUDIT: tanımsız katmanlara başvurular: __ocs_fmt_0__
|
.audit-error-s-warning-s-found = AUDIT: __ocs_fmt_0__ hata, __ocs_fmt_1__ uyarı bulundu.
|
||||||
.audit-report-only-no-automatic-repair-performe = AUDIT: yalnızca rapor oluşturuldu; otomatik onarım yapılmadı.
|
.audit-repair-s-applied-issue-s-left = AUDIT: __ocs_fmt_0__ onarım uygulandı, __ocs_fmt_1__ sorun çözülemedi.
|
||||||
.audit-scanned-total-object-s = AUDIT: __ocs_fmt_0__ nesne tarandı.
|
.audit-scanned-total-object-s = AUDIT: __ocs_fmt_0__ nesne tarandı.
|
||||||
.above-text = Metnin üstünde
|
.above-text = Metnin üstünde
|
||||||
.active-dim-style-set-to-name-arg = Etkin ölçü stili "__ocs_fmt_0__" olarak ayarlandı.
|
.active-dim-style-set-to-name-arg = Etkin ölçü stili "__ocs_fmt_0__" olarak ayarlandı.
|
||||||
|
|||||||
@@ -224,9 +224,7 @@ recovery =
|
|||||||
.failed-description = 修复未能生成可用的图形数据。请查看报告并尝试备份或自动保存的副本。
|
.failed-description = 修复未能生成可用的图形数据。请查看报告并尝试备份或自动保存的副本。
|
||||||
.entities-checked = 已检查实体
|
.entities-checked = 已检查实体
|
||||||
.issues-found = 发现的问题
|
.issues-found = 发现的问题
|
||||||
.entities-removed = 已删除实体
|
|
||||||
.references-checked = 已检查参照
|
.references-checked = 已检查参照
|
||||||
.referenced-entities-removed = 已删除被参照实体
|
|
||||||
.references-unavailable = 不可用参照
|
.references-unavailable = 不可用参照
|
||||||
.log-path = 修复日志
|
.log-path = 修复日志
|
||||||
.log-write-failed = 无法写入修复日志
|
.log-write-failed = 无法写入修复日志
|
||||||
@@ -2578,8 +2576,6 @@ file =
|
|||||||
.usage-undo-number-of-steps = 用法: UNDO [number of steps]
|
.usage-undo-number-of-steps = 用法: UNDO [number of steps]
|
||||||
.used-for-the-first-save-of-a-new-drawing-exist = 用于新图形的首次保存。现有图形会保留其自身的文件类型和版本。
|
.used-for-the-first-save-of-a-new-drawing-exist = 用于新图形的首次保存。现有图形会保留其自身的文件类型和版本。
|
||||||
.visual-style-label = 视觉风格: __ocs_fmt_0__.
|
.visual-style-label = 视觉风格: __ocs_fmt_0__.
|
||||||
.warning-corrupt-entities-dropped-parser-junk-b = 警告:已丢弃 __ocs_fmt_0__ 个损坏对象(解析数据无效——法线或计数错误)
|
|
||||||
.warning-corrupt-xref-entities-dropped = 警告:已丢弃 __ocs_fmt_0__ 个损坏的 xref 对象
|
|
||||||
.xref-loaded = XREF已装入"__ocs_fmt_0__"
|
.xref-loaded = XREF已装入"__ocs_fmt_0__"
|
||||||
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: 无法创建传输 ZIP(__ocs_fmt_1__)。
|
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: 无法创建传输 ZIP(__ocs_fmt_1__)。
|
||||||
.cmd-cannot-create-folder-e = __ocs_fmt_0__:无法创建文件夹(__ocs_fmt_1__).
|
.cmd-cannot-create-folder-e = __ocs_fmt_0__:无法创建文件夹(__ocs_fmt_1__).
|
||||||
@@ -5621,9 +5617,9 @@ styles =
|
|||||||
.aci-color-index = ACI 颜色索引
|
.aci-color-index = ACI 颜色索引
|
||||||
.aci = ACI:
|
.aci = ACI:
|
||||||
.audit-no-issues-found = AUDIT:没有找到问题。
|
.audit-no-issues-found = AUDIT:没有找到问题。
|
||||||
.audit-reference-s-to-undefined-block-s = AUDIT: 未定义块的引用 : __ocs_fmt_0__
|
.audit-fix-any-errors-detected = AUDIT 修复检测到的错误? [是 / 否] <否>:
|
||||||
.audit-reference-s-to-undefined-layer-s = AUDIT: 未定义层的参考:__ocs_fmt_0__
|
.audit-error-s-warning-s-found = AUDIT: 发现 __ocs_fmt_0__ 个错误,__ocs_fmt_1__ 个警告。
|
||||||
.audit-report-only-no-automatic-repair-performe = AUDIT:只报告——没有进行自动修复。
|
.audit-repair-s-applied-issue-s-left = AUDIT: 已应用 __ocs_fmt_0__ 项修复,__ocs_fmt_1__ 个问题未解决。
|
||||||
.audit-scanned-total-object-s = AUDIT: 扫描__ocs_fmt_0__对象。
|
.audit-scanned-total-object-s = AUDIT: 扫描__ocs_fmt_0__对象。
|
||||||
.above-text = 上方为文本
|
.above-text = 上方为文本
|
||||||
.active-dim-style-set-to-name-arg = 当前标注样式已设为“__ocs_fmt_0__”
|
.active-dim-style-set-to-name-arg = 当前标注样式已设为“__ocs_fmt_0__”
|
||||||
|
|||||||
@@ -224,9 +224,7 @@ recovery =
|
|||||||
.failed-description = 修復未能產生可用的圖形資料。請查看報告並嘗試備份或自動儲存的副本。
|
.failed-description = 修復未能產生可用的圖形資料。請查看報告並嘗試備份或自動儲存的副本。
|
||||||
.entities-checked = 已檢查實體
|
.entities-checked = 已檢查實體
|
||||||
.issues-found = 發現的問題
|
.issues-found = 發現的問題
|
||||||
.entities-removed = 已刪除實體
|
|
||||||
.references-checked = 已檢查參照
|
.references-checked = 已檢查參照
|
||||||
.referenced-entities-removed = 已刪除被參照實體
|
|
||||||
.references-unavailable = 不可用參照
|
.references-unavailable = 不可用參照
|
||||||
.log-path = 修復日誌
|
.log-path = 修復日誌
|
||||||
.log-write-failed = 無法寫入修復日誌
|
.log-write-failed = 無法寫入修復日誌
|
||||||
@@ -2590,8 +2588,6 @@ file =
|
|||||||
.usage-undo-number-of-steps = 用法: UNDO [number of steps]
|
.usage-undo-number-of-steps = 用法: UNDO [number of steps]
|
||||||
.used-for-the-first-save-of-a-new-drawing-exist = 用於新圖形的首次儲存。現有圖形會保留其自身的檔案類型和版本。
|
.used-for-the-first-save-of-a-new-drawing-exist = 用於新圖形的首次儲存。現有圖形會保留其自身的檔案類型和版本。
|
||||||
.visual-style-label = 視覺風格: __ocs_fmt_0__.
|
.visual-style-label = 視覺風格: __ocs_fmt_0__.
|
||||||
.warning-corrupt-entities-dropped-parser-junk-b = 警告:已丟棄 __ocs_fmt_0__ 個損壞物件(解析資料無效——法線或計數錯誤)
|
|
||||||
.warning-corrupt-xref-entities-dropped = 警告:已丟棄 __ocs_fmt_0__ 個損壞的 xref 物件
|
|
||||||
.xref-loaded = XREF已載入"__ocs_fmt_0__"
|
.xref-loaded = XREF已載入"__ocs_fmt_0__"
|
||||||
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: 無法建立傳送 ZIP(__ocs_fmt_1__)。
|
.cmd-cannot-build-the-transmittal-zip-e = __ocs_fmt_0__: 無法建立傳送 ZIP(__ocs_fmt_1__)。
|
||||||
.cmd-cannot-create-folder-e = __ocs_fmt_0__:無法建立資料夾(__ocs_fmt_1__).
|
.cmd-cannot-create-folder-e = __ocs_fmt_0__:無法建立資料夾(__ocs_fmt_1__).
|
||||||
@@ -5633,9 +5629,9 @@ styles =
|
|||||||
.aci-color-index = ACI 顏色索引
|
.aci-color-index = ACI 顏色索引
|
||||||
.aci = ACI:
|
.aci = ACI:
|
||||||
.audit-no-issues-found = AUDIT:沒有找到問題。
|
.audit-no-issues-found = AUDIT:沒有找到問題。
|
||||||
.audit-reference-s-to-undefined-block-s = AUDIT: 未定義圖塊的引用 : __ocs_fmt_0__
|
.audit-fix-any-errors-detected = AUDIT 修復偵測到的錯誤? [是 / 否] <否>:
|
||||||
.audit-reference-s-to-undefined-layer-s = AUDIT: 未定義層的參考:__ocs_fmt_0__
|
.audit-error-s-warning-s-found = AUDIT: 發現 __ocs_fmt_0__ 個錯誤,__ocs_fmt_1__ 個警告。
|
||||||
.audit-report-only-no-automatic-repair-performe = AUDIT:只報告——沒有進行自動修復。
|
.audit-repair-s-applied-issue-s-left = AUDIT: 已套用 __ocs_fmt_0__ 項修復,__ocs_fmt_1__ 個問題未解決。
|
||||||
.audit-scanned-total-object-s = AUDIT: 掃描__ocs_fmt_0__物件。
|
.audit-scanned-total-object-s = AUDIT: 掃描__ocs_fmt_0__物件。
|
||||||
.above-text = 上方為文字
|
.above-text = 上方為文字
|
||||||
.active-dim-style-set-to-name-arg = 目前標註樣式已設為“__ocs_fmt_0__”
|
.active-dim-style-set-to-name-arg = 目前標註樣式已設為“__ocs_fmt_0__”
|
||||||
|
|||||||
Generated
+11
-1
@@ -1245,6 +1245,15 @@ dependencies = [
|
|||||||
"thiserror 1.0.69",
|
"thiserror 1.0.69",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "oem_cp"
|
||||||
|
version = "2.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8c7959d3349f484aec36462f98226983578bf7d33f9b034c32967489c7000e1f"
|
||||||
|
dependencies = [
|
||||||
|
"phf 0.11.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.21.4"
|
version = "1.21.4"
|
||||||
@@ -1264,7 +1273,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opencadcodec"
|
name = "opencadcodec"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
source = "git+https://github.com/HakanSeven12/opencadcodec.git?rev=102f04c#102f04c8ecda1cd409f7ecc4b6eab2dc895c9095"
|
source = "git+https://github.com/HakanSeven12/opencadcodec.git?rev=325fa98#325fa98d2b881f48e106a830d5cf161624f63131"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
@@ -1276,6 +1285,7 @@ dependencies = [
|
|||||||
"itoa",
|
"itoa",
|
||||||
"memmap2",
|
"memmap2",
|
||||||
"nom",
|
"nom",
|
||||||
|
"oem_cp",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rayon",
|
"rayon",
|
||||||
"ryu",
|
"ryu",
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
viewport.twist_angle = std::f64::consts::FRAC_PI_2;
|
viewport.twist_angle = std::f64::consts::FRAC_PI_2;
|
||||||
viewport.view_target = Vector3::new(5.0, 10.0, 0.0);
|
viewport.view_target = Vector3::new(5.0, 10.0, 0.0);
|
||||||
}
|
}
|
||||||
document.add_entity_to_layout(EntityType::Viewport(viewport), "Sheet")?;
|
document.add_entity_to_layout(EntityType::Viewport(Box::new(viewport)), "Sheet")?;
|
||||||
|
|
||||||
let mut file = std::fs::OpenOptions::new()
|
let mut file = std::fs::OpenOptions::new()
|
||||||
.write(true)
|
.write(true)
|
||||||
|
|||||||
@@ -406,7 +406,7 @@ mod ocs {
|
|||||||
text.rotation = rotation;
|
text.rotation = rotation;
|
||||||
host_ctx::with_host(|host| {
|
host_ctx::with_host(|host| {
|
||||||
host_ctx::ensure_undo_started(host);
|
host_ctx::ensure_undo_started(host);
|
||||||
host.add_entity(EntityType::MText(text)).value()
|
host.add_entity(EntityType::MText(Box::new(text))).value()
|
||||||
})
|
})
|
||||||
.ok_or_else(|| vm.new_runtime_error("ocs: not running inside a PY_ command".to_owned()))
|
.ok_or_else(|| vm.new_runtime_error("ocs: not running inside a PY_ command".to_owned()))
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-33
@@ -762,7 +762,7 @@ impl OpenCADStudio {
|
|||||||
Err(e) => return err(format!("open: {e}")),
|
Err(e) => return err(format!("open: {e}")),
|
||||||
};
|
};
|
||||||
match crate::io::load_bytes_finalized(&path_buf, bytes) {
|
match crate::io::load_bytes_finalized(&path_buf, bytes) {
|
||||||
Ok((doc, dropped)) => {
|
Ok(doc) => {
|
||||||
let i = self.active_tab;
|
let i = self.active_tab;
|
||||||
self.tabs[i].scene.clear();
|
self.tabs[i].scene.clear();
|
||||||
self.tabs[i].scene.document = doc;
|
self.tabs[i].scene.document = doc;
|
||||||
@@ -784,13 +784,7 @@ impl OpenCADStudio {
|
|||||||
// The opened document settled (API v9): the post-op
|
// The opened document settled (API v9): the post-op
|
||||||
// boundary announces `DocumentOpened` once for this load.
|
// boundary announces `DocumentOpened` once for this load.
|
||||||
self.tabs[i].note_document_loaded();
|
self.tabs[i].note_document_loaded();
|
||||||
let mut summary = self.entity_summary();
|
self.entity_summary()
|
||||||
if dropped > 0 {
|
|
||||||
if let Some(obj) = summary.as_object_mut() {
|
|
||||||
obj.insert("purged".to_string(), json!(dropped));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
summary
|
|
||||||
}
|
}
|
||||||
Err(e) => err(format!("open: {e}")),
|
Err(e) => err(format!("open: {e}")),
|
||||||
}
|
}
|
||||||
@@ -1903,8 +1897,7 @@ mod tests {
|
|||||||
fingerprint: None,
|
fingerprint: None,
|
||||||
});
|
});
|
||||||
let bytes = std::fs::read(&path).expect("read the fixture back");
|
let bytes = std::fs::read(&path).expect("read the fixture back");
|
||||||
let (document, _dropped) =
|
let document = crate::io::load_bytes_finalized(&path, bytes).expect("reparse the fixture");
|
||||||
crate::io::load_bytes_finalized(&path, bytes).expect("reparse the fixture");
|
|
||||||
let caches = crate::scene::build_derived_caches_with_progress(&document, &|_| {}, None);
|
let caches = crate::scene::build_derived_caches_with_progress(&document, &|_| {}, None);
|
||||||
let _ = plugin_dispatch_log();
|
let _ = plugin_dispatch_log();
|
||||||
let _ = app.update(crate::app::Message::FileOpened(
|
let _ = app.update(crate::app::Message::FileOpened(
|
||||||
@@ -2129,7 +2122,7 @@ mod tests {
|
|||||||
dimension.definition_point = Vector3::new(0.0, 5.0, 0.0);
|
dimension.definition_point = Vector3::new(0.0, 5.0, 0.0);
|
||||||
dimension.base.text_middle_point = Vector3::new(5.0, 5.0, 0.0);
|
dimension.base.text_middle_point = Vector3::new(5.0, 5.0, 0.0);
|
||||||
document
|
document
|
||||||
.add_entity(EntityType::Dimension(Dimension::Linear(dimension)))
|
.add_entity(EntityType::Dimension(Box::new(Dimension::Linear(dimension))))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
crate::modules::draw::modify::explode::bake_dimension_blocks(&mut document);
|
crate::modules::draw::modify::explode::bake_dimension_blocks(&mut document);
|
||||||
|
|
||||||
@@ -2152,7 +2145,7 @@ mod tests {
|
|||||||
dimension.base.text_middle_point = Vector3::new(5.0, 5.0, 0.0);
|
dimension.base.text_middle_point = Vector3::new(5.0, 5.0, 0.0);
|
||||||
app.tabs[app.active_tab]
|
app.tabs[app.active_tab]
|
||||||
.scene
|
.scene
|
||||||
.add_entity(EntityType::Dimension(Dimension::Linear(dimension)));
|
.add_entity(EntityType::Dimension(Box::new(Dimension::Linear(dimension))));
|
||||||
let path = std::env::temp_dir().join(format!(
|
let path = std::env::temp_dir().join(format!(
|
||||||
"ocs_verified_dimension_{}_{}.dwg",
|
"ocs_verified_dimension_{}_{}.dwg",
|
||||||
std::process::id(),
|
std::process::id(),
|
||||||
@@ -2190,7 +2183,7 @@ mod tests {
|
|||||||
let i = app.active_tab;
|
let i = app.active_tab;
|
||||||
app.tabs[i]
|
app.tabs[i]
|
||||||
.scene
|
.scene
|
||||||
.add_entity(EntityType::Dimension(Dimension::Linear(dimension)));
|
.add_entity(EntityType::Dimension(Box::new(Dimension::Linear(dimension))));
|
||||||
let path = std::env::temp_dir().join(format!(
|
let path = std::env::temp_dir().join(format!(
|
||||||
"ocs_verified_dimension_follow_up_{}_{}.dwg",
|
"ocs_verified_dimension_follow_up_{}_{}.dwg",
|
||||||
std::process::id(),
|
std::process::id(),
|
||||||
@@ -2240,7 +2233,7 @@ mod tests {
|
|||||||
app.tabs[i]
|
app.tabs[i]
|
||||||
.scene
|
.scene
|
||||||
.document
|
.document
|
||||||
.add_entity(EntityType::Dimension(Dimension::Linear(d)))
|
.add_entity(EntityType::Dimension(Box::new(Dimension::Linear(d))))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let path = std::env::temp_dir().join(format!(
|
let path = std::env::temp_dir().join(format!(
|
||||||
"ocs_verified_dim_{}_{}.dwg",
|
"ocs_verified_dim_{}_{}.dwg",
|
||||||
@@ -2330,7 +2323,7 @@ mod tests {
|
|||||||
viewport.width = 100.0;
|
viewport.width = 100.0;
|
||||||
viewport.height = 50.0;
|
viewport.height = 50.0;
|
||||||
viewport.turn_on();
|
viewport.turn_on();
|
||||||
scene.add_entity(codec::EntityType::Viewport(viewport));
|
scene.add_entity(codec::EntityType::Viewport(Box::new(viewport)));
|
||||||
for entity in scene.document.entities_mut() {
|
for entity in scene.document.entities_mut() {
|
||||||
if let codec::EntityType::Viewport(viewport) = entity {
|
if let codec::EntityType::Viewport(viewport) = entity {
|
||||||
viewport.status.grid_on = true;
|
viewport.status.grid_on = true;
|
||||||
@@ -2774,7 +2767,7 @@ mod tests {
|
|||||||
codec::MText::with_value("\\A1;10.5000", codec::types::Vector3::new(10.0, 20.0, 0.0));
|
codec::MText::with_value("\\A1;10.5000", codec::types::Vector3::new(10.0, 20.0, 0.0));
|
||||||
app.tabs[i]
|
app.tabs[i]
|
||||||
.scene
|
.scene
|
||||||
.add_entity(codec::EntityType::MText(mtext));
|
.add_entity(codec::EntityType::MText(Box::new(mtext)));
|
||||||
|
|
||||||
let q = app.automation_op(
|
let q = app.automation_op(
|
||||||
r#"{"op":"query","type":"MTEXT","detail":"full","fields":["value","text","height","bounds"]}"#,
|
r#"{"op":"query","type":"MTEXT","detail":"full","fields":["value","text","height","bounds"]}"#,
|
||||||
@@ -3642,7 +3635,7 @@ mod tests {
|
|||||||
let mut dst_mtext = MText::new();
|
let mut dst_mtext = MText::new();
|
||||||
dst_mtext.value = "DSTM".into();
|
dst_mtext.value = "DSTM".into();
|
||||||
dst_mtext.height = 2.0;
|
dst_mtext.height = 2.0;
|
||||||
let dst_mtext_h = app.tabs[i].scene.add_entity(EntityType::MText(dst_mtext));
|
let dst_mtext_h = app.tabs[i].scene.add_entity(EntityType::MText(Box::new(dst_mtext)));
|
||||||
|
|
||||||
// Drive the interactive command exactly as the viewport does:
|
// Drive the interactive command exactly as the viewport does:
|
||||||
// phase 1 source pick, phase 2 destination selection.
|
// phase 1 source pick, phase 2 destination selection.
|
||||||
@@ -3839,7 +3832,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn open_finalizes_and_purges_like_the_ui_open_path() {
|
fn open_finalizes_like_the_ui_open_path() {
|
||||||
let mut app = OpenCADStudio::new_for_test();
|
let mut app = OpenCADStudio::new_for_test();
|
||||||
let stale = codec::Handle::from(9999);
|
let stale = codec::Handle::from(9999);
|
||||||
app.tabs[app.active_tab].scene.solid_models.insert(
|
app.tabs[app.active_tab].scene.solid_models.insert(
|
||||||
@@ -3857,26 +3850,13 @@ mod tests {
|
|||||||
good.center = codec::types::Vector3::new(5.0, 5.0, 0.0);
|
good.center = codec::types::Vector3::new(5.0, 5.0, 0.0);
|
||||||
good.radius = 2.0;
|
good.radius = 2.0;
|
||||||
doc.add_entity(codec::EntityType::Circle(good)).unwrap();
|
doc.add_entity(codec::EntityType::Circle(good)).unwrap();
|
||||||
let mut corrupt = codec::entities::Circle::new();
|
let bytes = crate::io::save_to_bytes(&doc, "dxf", doc.version).expect("save the fixture");
|
||||||
corrupt.center = codec::types::Vector3::new(1.0, 1.0, 0.0);
|
|
||||||
// An absurd radius is rejected; a zero radius is valid.
|
|
||||||
corrupt.radius = 1.0e11;
|
|
||||||
doc.add_entity(codec::EntityType::Circle(corrupt)).unwrap();
|
|
||||||
let bytes = crate::io::save_to_bytes(&doc, "dxf", doc.version)
|
|
||||||
.expect("save a document containing a corrupt entity");
|
|
||||||
std::fs::write(&path, bytes).unwrap();
|
std::fs::write(&path, bytes).unwrap();
|
||||||
|
|
||||||
let p = path.to_string_lossy().replace('\\', "\\\\");
|
let p = path.to_string_lossy().replace('\\', "\\\\");
|
||||||
let result = app.automation_op(&format!(r#"{{"op":"open","path":"{p}"}}"#));
|
let result = app.automation_op(&format!(r#"{{"op":"open","path":"{p}"}}"#));
|
||||||
assert_eq!(result["ok"], true, "{}", result["error"]);
|
assert_eq!(result["ok"], true, "{}", result["error"]);
|
||||||
assert_eq!(
|
assert_eq!(result["total"], 1);
|
||||||
result["total"], 1,
|
|
||||||
"the corrupt circle must not survive the open"
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
result["purged"], 1,
|
|
||||||
"the purge count must be reported, matching the UI open path's diagnostics"
|
|
||||||
);
|
|
||||||
|
|
||||||
let i = app.active_tab;
|
let i = app.active_tab;
|
||||||
assert!(!app.tabs[i].scene.solid_models.contains_key(&stale));
|
assert!(!app.tabs[i].scene.solid_models.contains_key(&stale));
|
||||||
|
|||||||
@@ -1405,7 +1405,7 @@ mod paste_entities_kernel_tests {
|
|||||||
fn remaps_leader_annotation_link_to_pasted_handles() {
|
fn remaps_leader_annotation_link_to_pasted_handles() {
|
||||||
let mut seed = codec::CadDocument::new();
|
let mut seed = codec::CadDocument::new();
|
||||||
let note = seed
|
let note = seed
|
||||||
.add_entity(codec::EntityType::MText(codec::entities::MText::new()))
|
.add_entity(codec::EntityType::MText(Box::new(codec::entities::MText::new())))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let mut leader = codec::entities::Leader::default();
|
let mut leader = codec::entities::Leader::default();
|
||||||
leader.annotation_handle = note;
|
leader.annotation_handle = note;
|
||||||
|
|||||||
@@ -36,10 +36,12 @@ impl OpenCADStudio {
|
|||||||
) {
|
) {
|
||||||
let i = self.active_tab;
|
let i = self.active_tab;
|
||||||
let valid = matches!(
|
let valid = matches!(
|
||||||
self.tabs[i].scene.document.get_entity(dimension),
|
self.tabs[i]
|
||||||
Some(codec::EntityType::Dimension(
|
.scene
|
||||||
codec::entities::Dimension::Linear(_) | codec::entities::Dimension::Aligned(_)
|
.document
|
||||||
))
|
.get_entity(dimension)
|
||||||
|
.and_then(crate::entities::dimension::as_dimension),
|
||||||
|
Some(codec::entities::Dimension::Linear(_) | codec::entities::Dimension::Aligned(_))
|
||||||
);
|
);
|
||||||
if !valid {
|
if !valid {
|
||||||
self.command_line.push_error(
|
self.command_line.push_error(
|
||||||
@@ -415,8 +417,12 @@ fn apply_dimspace(
|
|||||||
requested_spacing: Option<f64>,
|
requested_spacing: Option<f64>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
use codec::entities::Dimension;
|
use codec::entities::Dimension;
|
||||||
let (axis, normal, definition, auto_spacing) = match scene.document.get_entity(base_h) {
|
let base = scene
|
||||||
Some(codec::EntityType::Dimension(dimension @ Dimension::Linear(d))) => {
|
.document
|
||||||
|
.get_entity(base_h)
|
||||||
|
.and_then(crate::entities::dimension::as_dimension);
|
||||||
|
let (axis, normal, definition, auto_spacing) = match base {
|
||||||
|
Some(dimension @ Dimension::Linear(d)) => {
|
||||||
let spacing = dimension_auto_spacing(
|
let spacing = dimension_auto_spacing(
|
||||||
&scene.document,
|
&scene.document,
|
||||||
dimension,
|
dimension,
|
||||||
@@ -433,7 +439,7 @@ fn apply_dimspace(
|
|||||||
spacing,
|
spacing,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Some(codec::EntityType::Dimension(dimension @ Dimension::Aligned(d))) => {
|
Some(dimension @ Dimension::Aligned(d)) => {
|
||||||
let spacing = dimension_auto_spacing(
|
let spacing = dimension_auto_spacing(
|
||||||
&scene.document,
|
&scene.document,
|
||||||
dimension,
|
dimension,
|
||||||
@@ -471,7 +477,7 @@ fn apply_dimspace(
|
|||||||
kernel::space::move_to_dimension_spacing([p.x, p.y, p.z], frame, target);
|
kernel::space::move_to_dimension_spacing([p.x, p.y, p.z], frame, target);
|
||||||
*p = codec::types::Vector3::new(point[0], point[1], point[2]);
|
*p = codec::types::Vector3::new(point[0], point[1], point[2]);
|
||||||
};
|
};
|
||||||
match dim {
|
match &mut **dim {
|
||||||
Dimension::Linear(d) => {
|
Dimension::Linear(d) => {
|
||||||
slide(&mut d.definition_point);
|
slide(&mut d.definition_point);
|
||||||
d.base.definition_point = d.definition_point;
|
d.base.definition_point = d.definition_point;
|
||||||
|
|||||||
@@ -39,10 +39,8 @@ impl OpenCADStudio {
|
|||||||
let delta_safe = self.delta_add_safe(i, &entity);
|
let delta_safe = self.delta_add_safe(i, &entity);
|
||||||
let pending = self.begin_undo(i, label, 1, delta_safe);
|
let pending = self.begin_undo(i, label, 1, delta_safe);
|
||||||
let is_associative_dimension = matches!(
|
let is_associative_dimension = matches!(
|
||||||
entity,
|
crate::entities::dimension::as_dimension(&entity),
|
||||||
codec::EntityType::Dimension(
|
Some(codec::entities::Dimension::Linear(_) | codec::entities::Dimension::Aligned(_))
|
||||||
codec::entities::Dimension::Linear(_) | codec::entities::Dimension::Aligned(_)
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
let association_enabled = self.tabs[i].scene.document.header.dimension_associativity == 2;
|
let association_enabled = self.tabs[i].scene.document.header.dimension_associativity == 2;
|
||||||
let committed = if preserve_commit_layer {
|
let committed = if preserve_commit_layer {
|
||||||
@@ -257,10 +255,8 @@ impl OpenCADStudio {
|
|||||||
};
|
};
|
||||||
let pending = self.begin_undo(i, label, 1, delta_safe);
|
let pending = self.begin_undo(i, label, 1, delta_safe);
|
||||||
let is_associative_dimension = matches!(
|
let is_associative_dimension = matches!(
|
||||||
entity,
|
crate::entities::dimension::as_dimension(&entity),
|
||||||
codec::EntityType::Dimension(
|
Some(codec::entities::Dimension::Linear(_) | codec::entities::Dimension::Aligned(_))
|
||||||
codec::entities::Dimension::Linear(_) | codec::entities::Dimension::Aligned(_)
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
let association_enabled = self.tabs[i].scene.document.header.dimension_associativity == 2;
|
let association_enabled = self.tabs[i].scene.document.header.dimension_associativity == 2;
|
||||||
let committed = if preserve_commit_layer {
|
let committed = if preserve_commit_layer {
|
||||||
@@ -324,8 +320,8 @@ impl OpenCADStudio {
|
|||||||
let label = self.history_label_from_active_cmd(i, "DIMENSION");
|
let label = self.history_label_from_active_cmd(i, "DIMENSION");
|
||||||
let association_mode = self.tabs[i].scene.document.header.dimension_associativity;
|
let association_mode = self.tabs[i].scene.document.header.dimension_associativity;
|
||||||
let single_source_dimension = matches!(
|
let single_source_dimension = matches!(
|
||||||
&entity,
|
crate::entities::dimension::as_dimension(&entity),
|
||||||
codec::EntityType::Dimension(codec::entities::Dimension::Ordinate(_))
|
Some(codec::entities::Dimension::Ordinate(_))
|
||||||
);
|
);
|
||||||
// A dimension placed on the sheet but measuring model geometry
|
// A dimension placed on the sheet but measuring model geometry
|
||||||
// through a viewport carries the compensation as a negative
|
// through a viewport carries the compensation as a negative
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ impl OpenCADStudio {
|
|||||||
Operation::Rotate(degrees) => {
|
Operation::Rotate(degrees) => {
|
||||||
dimension.base_mut().text_rotation = degrees.to_radians();
|
dimension.base_mut().text_rotation = degrees.to_radians();
|
||||||
}
|
}
|
||||||
Operation::Oblique(degrees) => match dimension {
|
Operation::Oblique(degrees) => match &mut **dimension {
|
||||||
codec::entities::Dimension::Linear(value) => {
|
codec::entities::Dimension::Linear(value) => {
|
||||||
value.ext_line_rotation = degrees.to_radians();
|
value.ext_line_rotation = degrees.to_radians();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -463,7 +463,7 @@ impl OpenCADStudio {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
match dim {
|
match &mut **dim {
|
||||||
Dimension::Linear(d) => {
|
Dimension::Linear(d) => {
|
||||||
stretched |= mv(&mut d.first_point);
|
stretched |= mv(&mut d.first_point);
|
||||||
stretched |= mv(&mut d.second_point);
|
stretched |= mv(&mut d.second_point);
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ impl OpenCADStudio {
|
|||||||
});
|
});
|
||||||
let label = self.history_label_from_active_cmd(i, "MVIEW");
|
let label = self.history_label_from_active_cmd(i, "MVIEW");
|
||||||
let pending = self.begin_undo(i, label, 1, true);
|
let pending = self.begin_undo(i, label, 1, true);
|
||||||
let handle = self.commit_entity_handle(codec::EntityType::Viewport(viewport));
|
let handle = self.commit_entity_handle(codec::EntityType::Viewport(Box::new(viewport)));
|
||||||
if let (Some(handle), Some(saved)) = (handle, saved_view) {
|
if let (Some(handle), Some(saved)) = (handle, saved_view) {
|
||||||
if let Some(codec::EntityType::Viewport(viewport)) =
|
if let Some(codec::EntityType::Viewport(viewport)) =
|
||||||
self.tabs[i].scene.document.get_entity_mut(handle)
|
self.tabs[i].scene.document.get_entity_mut(handle)
|
||||||
@@ -244,7 +244,8 @@ impl OpenCADStudio {
|
|||||||
viewport.id = 2;
|
viewport.id = 2;
|
||||||
viewport.clip_boundary_handle = clip_handle;
|
viewport.clip_boundary_handle = clip_handle;
|
||||||
viewport.status.non_rectangular_clipping = !clip_handle.is_null();
|
viewport.status.non_rectangular_clipping = !clip_handle.is_null();
|
||||||
let viewport_handle = self.commit_entity_handle(codec::EntityType::Viewport(viewport));
|
let viewport_handle =
|
||||||
|
self.commit_entity_handle(codec::EntityType::Viewport(Box::new(viewport)));
|
||||||
if let Some(viewport_handle) = viewport_handle {
|
if let Some(viewport_handle) = viewport_handle {
|
||||||
if !created_boundary {
|
if !created_boundary {
|
||||||
let before = self.tabs[i]
|
let before = self.tabs[i]
|
||||||
|
|||||||
@@ -1128,7 +1128,7 @@ impl OpenCADStudio {
|
|||||||
.filter(|br| reload_keys.contains(&br.handle.value()))
|
.filter(|br| reload_keys.contains(&br.handle.value()))
|
||||||
.map(|br| br.handle)
|
.map(|br| br.handle)
|
||||||
.collect();
|
.collect();
|
||||||
let (infos, _dropped) = crate::io::xref::resolve_xrefs_for_keys(
|
let infos = crate::io::xref::resolve_xrefs_for_keys(
|
||||||
&mut self.tabs[i].scene.document,
|
&mut self.tabs[i].scene.document,
|
||||||
base_dir,
|
base_dir,
|
||||||
&handles,
|
&handles,
|
||||||
@@ -1674,7 +1674,7 @@ impl OpenCADStudio {
|
|||||||
self.tabs[i].xref_unloaded.remove(key);
|
self.tabs[i].xref_unloaded.remove(key);
|
||||||
self.tabs[i].xref_stat_cache.remove(key);
|
self.tabs[i].xref_stat_cache.remove(key);
|
||||||
}
|
}
|
||||||
let (infos, _dropped) = crate::io::xref::resolve_xrefs(
|
let infos = crate::io::xref::resolve_xrefs(
|
||||||
&mut self.tabs[i].scene.document,
|
&mut self.tabs[i].scene.document,
|
||||||
&base_dir,
|
&base_dir,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -294,7 +294,7 @@ impl OpenCADStudio {
|
|||||||
} else {
|
} else {
|
||||||
line.layer
|
line.layer
|
||||||
};
|
};
|
||||||
scene.add_entity(codec::EntityType::MText(mtext));
|
scene.add_entity(codec::EntityType::MText(Box::new(mtext)));
|
||||||
erase.extend(line.handles);
|
erase.extend(line.handles);
|
||||||
}
|
}
|
||||||
erase.sort();
|
erase.sort();
|
||||||
|
|||||||
@@ -2389,7 +2389,7 @@ impl OpenCADStudio {
|
|||||||
Vector3::new(mv.center.x - mv.target.x, mv.center.y - mv.target.y, 0.0);
|
Vector3::new(mv.center.x - mv.target.x, mv.center.y - mv.target.y, 0.0);
|
||||||
vp.view_height = mv.height;
|
vp.view_height = mv.height;
|
||||||
vp.custom_scale = scale;
|
vp.custom_scale = scale;
|
||||||
scene.add_entity(codec::EntityType::Viewport(vp));
|
scene.add_entity(codec::EntityType::Viewport(Box::new(vp)));
|
||||||
// A paper-space named view of the same name frames it.
|
// A paper-space named view of the same name frames it.
|
||||||
let mut named = codec::tables::View::new(title.as_str());
|
let mut named = codec::tables::View::new(title.as_str());
|
||||||
named.handle = scene.document.allocate_handle();
|
named.handle = scene.document.allocate_handle();
|
||||||
|
|||||||
@@ -3671,53 +3671,62 @@ impl OpenCADStudio {
|
|||||||
.push_error(crate::tf!("COMPARE: {error}").as_ref()),
|
.push_error(crate::tf!("COMPARE: {error}").as_ref()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// AUDIT runs the codec's audit; `AUDIT Yes` also applies its
|
||||||
|
// repair, undoable as one step.
|
||||||
"AUDIT" => {
|
"AUDIT" => {
|
||||||
use std::collections::BTreeSet;
|
use crate::command::KeywordCommand;
|
||||||
let mut undefined_layers: BTreeSet<String> = BTreeSet::new();
|
let c = KeywordCommand::new(
|
||||||
let mut undefined_blocks: BTreeSet<String> = BTreeSet::new();
|
"AUDIT",
|
||||||
let mut total = 0usize;
|
"AUDIT Fix any errors detected? [Yes / No] <No>:",
|
||||||
{
|
vec![("Yes", "YES", None), ("No", "NO", None)],
|
||||||
|
)
|
||||||
|
.with_default("NO");
|
||||||
|
self.command_line.push_info(&c.prompt());
|
||||||
|
self.tabs[i].active_cmd = Some(Box::new(c));
|
||||||
|
}
|
||||||
|
cmd if cmd.starts_with("AUDIT ") => {
|
||||||
|
let fix = cmd[6..].trim().to_uppercase().starts_with('Y');
|
||||||
|
let report = self.tabs[i].scene.document.audit();
|
||||||
|
let total = {
|
||||||
let doc = &self.tabs[i].scene.document;
|
let doc = &self.tabs[i].scene.document;
|
||||||
for e in doc.entities() {
|
doc.entities().count() + doc.objects.len()
|
||||||
total += 1;
|
};
|
||||||
let layer = &e.common().layer;
|
|
||||||
if !layer.is_empty() && doc.layers.get(layer).is_none() {
|
|
||||||
undefined_layers.insert(layer.clone());
|
|
||||||
}
|
|
||||||
if let codec::EntityType::Insert(ins) = e {
|
|
||||||
if doc.block_records.get(&ins.block_name).is_none() {
|
|
||||||
undefined_blocks.insert(ins.block_name.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(crate::tf!("AUDIT: scanned {total} object(s).").as_ref());
|
.push_output(crate::tf!("AUDIT: scanned {total} object(s).").as_ref());
|
||||||
if undefined_layers.is_empty() && undefined_blocks.is_empty() {
|
if report.is_clean() {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(crate::t!("AUDIT: no issues found.").as_ref());
|
.push_output(crate::t!("AUDIT: no issues found.").as_ref());
|
||||||
} else {
|
return Some(Task::none());
|
||||||
if !undefined_layers.is_empty() {
|
}
|
||||||
self.command_line.push_error(
|
self.command_line.push_error(
|
||||||
crate::tf!(
|
crate::tf!(
|
||||||
"AUDIT: reference(s) to undefined layer(s): {}",
|
"AUDIT: {} error(s), {} warning(s) found.",
|
||||||
undefined_layers.into_iter().collect::<Vec<_>>().join(", ")
|
report.error_count(),
|
||||||
)
|
report.warning_count()
|
||||||
.as_ref(),
|
)
|
||||||
);
|
.as_ref(),
|
||||||
}
|
);
|
||||||
if !undefined_blocks.is_empty() {
|
// ponytail: first 50 issues only; the counts above cover the rest.
|
||||||
self.command_line.push_error(
|
for issue in report.issues.iter().take(50) {
|
||||||
crate::tf!(
|
self.command_line
|
||||||
"AUDIT: reference(s) to undefined block(s): {}",
|
.push_info(&format!(" {:?}: {}", issue.code, issue.message));
|
||||||
undefined_blocks.into_iter().collect::<Vec<_>>().join(", ")
|
}
|
||||||
)
|
if fix {
|
||||||
.as_ref(),
|
self.push_undo_snapshot(i, "AUDIT");
|
||||||
);
|
let repair = self.tabs[i].scene.document.repair();
|
||||||
}
|
self.command_line.push_output(
|
||||||
self.command_line.push_info(
|
crate::tf!(
|
||||||
crate::t!("AUDIT: report only — no automatic repair performed.").as_ref(),
|
"AUDIT: {} repair(s) applied, {} issue(s) left unresolved.",
|
||||||
|
repair.actions.len(),
|
||||||
|
repair.unresolved.len()
|
||||||
|
)
|
||||||
|
.as_ref(),
|
||||||
);
|
);
|
||||||
|
if !repair.actions.is_empty() {
|
||||||
|
self.tabs[i].dirty = true;
|
||||||
|
self.tabs[i].scene.rebuild_derived_caches();
|
||||||
|
self.refresh_layer_panel();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -126,10 +126,10 @@ mod tests {
|
|||||||
let i = app.active_tab;
|
let i = app.active_tab;
|
||||||
let first = app.tabs[i]
|
let first = app.tabs[i]
|
||||||
.scene
|
.scene
|
||||||
.add_entity(codec::EntityType::Viewport(codec::entities::Viewport::new()));
|
.add_entity(codec::EntityType::Viewport(Box::new(codec::entities::Viewport::new())));
|
||||||
let second = app.tabs[i]
|
let second = app.tabs[i]
|
||||||
.scene
|
.scene
|
||||||
.add_entity(codec::EntityType::Viewport(codec::entities::Viewport::new()));
|
.add_entity(codec::EntityType::Viewport(Box::new(codec::entities::Viewport::new())));
|
||||||
app.tabs[i].scene.active_viewport = Some(first);
|
app.tabs[i].scene.active_viewport = Some(first);
|
||||||
let _ = app.run_command_line("UCSFOLLOW 1");
|
let _ = app.run_command_line("UCSFOLLOW 1");
|
||||||
assert!(app.tabs[i].scene.ucs_follow());
|
assert!(app.tabs[i].scene.ucs_follow());
|
||||||
|
|||||||
@@ -1000,7 +1000,10 @@ impl OpenCADStudio {
|
|||||||
match self.tabs[i]
|
match self.tabs[i]
|
||||||
.scene
|
.scene
|
||||||
.document
|
.document
|
||||||
.add_entity_to_layout(codec::EntityType::Viewport(vp), &layout_name)
|
.add_entity_to_layout(
|
||||||
|
codec::EntityType::Viewport(Box::new(vp)),
|
||||||
|
&layout_name,
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Ok(handle) => {
|
Ok(handle) => {
|
||||||
self.tabs[i].scene.auto_fit_viewport(handle);
|
self.tabs[i].scene.auto_fit_viewport(handle);
|
||||||
@@ -2207,7 +2210,7 @@ mod tests {
|
|||||||
locked_hatch.common.layer = "LOCKED_LAYER".into();
|
locked_hatch.common.layer = "LOCKED_LAYER".into();
|
||||||
let h_locked_hatch = app.tabs[i]
|
let h_locked_hatch = app.tabs[i]
|
||||||
.scene
|
.scene
|
||||||
.add_entity_clone(EntityType::Hatch(locked_hatch));
|
.add_entity_clone(EntityType::Hatch(Box::new(locked_hatch)));
|
||||||
|
|
||||||
let h_line = app.tabs[i]
|
let h_line = app.tabs[i]
|
||||||
.scene
|
.scene
|
||||||
|
|||||||
@@ -1009,10 +1009,9 @@ impl OpenCADStudio {
|
|||||||
"new" => {
|
"new" => {
|
||||||
if let Some(template) = req["template"].as_str() {
|
if let Some(template) = req["template"].as_str() {
|
||||||
match self.apply_template(template) {
|
match self.apply_template(template) {
|
||||||
Ok(purged) => {
|
Ok(()) => {
|
||||||
self.set_control_result(json!({
|
self.set_control_result(json!({
|
||||||
"template": template,
|
"template": template,
|
||||||
"purged": purged,
|
|
||||||
"total": self.tabs[i].scene.document.entities().count(),
|
"total": self.tabs[i].scene.document.entities().count(),
|
||||||
}));
|
}));
|
||||||
Task::none()
|
Task::none()
|
||||||
|
|||||||
@@ -434,7 +434,7 @@ impl OpenCADStudio {
|
|||||||
/// `new` with `"template"` — the web build reads no files from a path, so
|
/// `new` with `"template"` — the web build reads no files from a path, so
|
||||||
/// a template is refused there rather than silently ignored.
|
/// a template is refused there rather than silently ignored.
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
pub(in crate::app) fn apply_template(&mut self, _template: &str) -> Result<usize, Value> {
|
pub(in crate::app) fn apply_template(&mut self, _template: &str) -> Result<(), Value> {
|
||||||
Err(failure(
|
Err(failure(
|
||||||
"invalid_request",
|
"invalid_request",
|
||||||
"starting from a template needs the desktop build",
|
"starting from a template needs the desktop build",
|
||||||
@@ -445,7 +445,7 @@ impl OpenCADStudio {
|
|||||||
/// file. Tables and styles come from the template; the document keeps no
|
/// file. Tables and styles come from the template; the document keeps no
|
||||||
/// source path.
|
/// source path.
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
pub(in crate::app) fn apply_template(&mut self, template: &str) -> Result<usize, Value> {
|
pub(in crate::app) fn apply_template(&mut self, template: &str) -> Result<(), Value> {
|
||||||
let path = std::path::PathBuf::from(template);
|
let path = std::path::PathBuf::from(template);
|
||||||
let bytes = self
|
let bytes = self
|
||||||
.read_drawing(&path)
|
.read_drawing(&path)
|
||||||
@@ -461,7 +461,7 @@ impl OpenCADStudio {
|
|||||||
} else {
|
} else {
|
||||||
path.clone()
|
path.clone()
|
||||||
};
|
};
|
||||||
let (mut document, purged) = crate::io::load_bytes_finalized(&load_path, bytes)
|
let mut document = crate::io::load_bytes_finalized(&load_path, bytes)
|
||||||
.map_err(|e| failure("template_failed", e))?;
|
.map_err(|e| failure("template_failed", e))?;
|
||||||
document.source_path = Some(path.to_string_lossy().into_owned());
|
document.source_path = Some(path.to_string_lossy().into_owned());
|
||||||
let i = self.active_tab;
|
let i = self.active_tab;
|
||||||
@@ -482,7 +482,7 @@ impl OpenCADStudio {
|
|||||||
// A whole document just became resident in the tab (API v9): the
|
// A whole document just became resident in the tab (API v9): the
|
||||||
// boundary announces `DocumentOpened` once.
|
// boundary announces `DocumentOpened` once.
|
||||||
self.tabs[i].note_document_loaded();
|
self.tabs[i].note_document_loaded();
|
||||||
Ok(purged)
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `file_identity` — stable per-document GUID (the drawing's SPMDOCUNIQUE value,
|
/// `file_identity` — stable per-document GUID (the drawing's SPMDOCUNIQUE value,
|
||||||
|
|||||||
@@ -352,7 +352,7 @@ impl OpenCADStudio {
|
|||||||
|
|
||||||
fn is_angular_dimension(entity: &EntityType) -> bool {
|
fn is_angular_dimension(entity: &EntityType) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
entity,
|
crate::entities::dimension::as_dimension(entity),
|
||||||
EntityType::Dimension(Dimension::Angular2Ln(_) | Dimension::Angular3Pt(_))
|
Some(Dimension::Angular2Ln(_) | Dimension::Angular3Pt(_))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -841,7 +841,7 @@ impl super::OpenCADStudio {
|
|||||||
// catastrophic cancellation. Insertion is a pure translation, so zeroing
|
// catastrophic cancellation. Insertion is a pure translation, so zeroing
|
||||||
// it keeps the layout's shape, wrapping and alignment identical.
|
// it keeps the layout's shape, wrapping and alignment identical.
|
||||||
mt.insertion_point = Vector3::new(0.0, 0.0, 0.0);
|
mt.insertion_point = Vector3::new(0.0, 0.0, 0.0);
|
||||||
let entity = EntityType::MText(mt.clone());
|
let entity = EntityType::MText(Box::new(mt.clone()));
|
||||||
let anno = 1.0;
|
let anno = 1.0;
|
||||||
let bg = self.tabs[i].scene.bg_color;
|
let bg = self.tabs[i].scene.bg_color;
|
||||||
let wires: Vec<WireModel> = tessellate::tessellate(
|
let wires: Vec<WireModel> = tessellate::tessellate(
|
||||||
@@ -1753,7 +1753,8 @@ impl super::OpenCADStudio {
|
|||||||
));
|
));
|
||||||
mt.insertion_point = codec::types::Vector3::new(position.x, position.y, position.z);
|
mt.insertion_point = codec::types::Vector3::new(position.x, position.y, position.z);
|
||||||
self.push_undo_snapshot(i, "MTEXT");
|
self.push_undo_snapshot(i, "MTEXT");
|
||||||
let handle = self.commit_entity_handle(plane.place_entity(EntityType::MText(mt)));
|
let handle =
|
||||||
|
self.commit_entity_handle(plane.place_entity(EntityType::MText(Box::new(mt))));
|
||||||
if annotative {
|
if annotative {
|
||||||
let scale = self.tabs[i].scene.creation_annotation_scale_handle();
|
let scale = self.tabs[i].scene.creation_annotation_scale_handle();
|
||||||
if let (Some(handle), Some(scale)) = (handle, scale) {
|
if let (Some(handle), Some(scale)) = (handle, scale) {
|
||||||
@@ -1869,7 +1870,8 @@ impl super::OpenCADStudio {
|
|||||||
));
|
));
|
||||||
mt.insertion_point = codec::types::Vector3::new(position.x, position.y, position.z);
|
mt.insertion_point = codec::types::Vector3::new(position.x, position.y, position.z);
|
||||||
self.push_undo_snapshot(i, "MTEXT");
|
self.push_undo_snapshot(i, "MTEXT");
|
||||||
let handle = self.commit_entity_handle(plane.place_entity(EntityType::MText(mt)));
|
let handle =
|
||||||
|
self.commit_entity_handle(plane.place_entity(EntityType::MText(Box::new(mt))));
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
if annotative {
|
if annotative {
|
||||||
let scale = self.tabs[i].scene.creation_annotation_scale_handle();
|
let scale = self.tabs[i].scene.creation_annotation_scale_handle();
|
||||||
@@ -1885,7 +1887,7 @@ impl super::OpenCADStudio {
|
|||||||
if let (Some(h), Some(ed)) = (handle, self.mtext_editor.as_mut()) {
|
if let (Some(h), Some(ed)) = (handle, self.mtext_editor.as_mut()) {
|
||||||
ed.editing = Some(h);
|
ed.editing = Some(h);
|
||||||
if let Some(EntityType::MText(mtext)) = self.tabs[i].scene.document.get_entity(h) {
|
if let Some(EntityType::MText(mtext)) = self.tabs[i].scene.document.get_entity(h) {
|
||||||
ed.original = Some(mtext.clone());
|
ed.original = Some((**mtext).clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -497,7 +497,7 @@ mod tests {
|
|||||||
vp.width = 200.;
|
vp.width = 200.;
|
||||||
vp.height = 100.;
|
vp.height = 100.;
|
||||||
vp.view_height = 50.;
|
vp.view_height = 50.;
|
||||||
let handle = scene.add_entity(codec::EntityType::Viewport(vp));
|
let handle = scene.add_entity(codec::EntityType::Viewport(Box::new(vp)));
|
||||||
scene.active_viewport = Some(handle);
|
scene.active_viewport = Some(handle);
|
||||||
let mut camera = scene.navigation_camera();
|
let mut camera = scene.navigation_camera();
|
||||||
camera.target = DVec3::new(120., 30., 8.);
|
camera.target = DVec3::new(120., 30., 8.);
|
||||||
|
|||||||
@@ -943,7 +943,7 @@ impl<'a> HostSession<'a> {
|
|||||||
frame.common.layer = layer;
|
frame.common.layer = layer;
|
||||||
}
|
}
|
||||||
self.push_undo("Embed picture");
|
self.push_undo("Embed picture");
|
||||||
let handle = self.add_entity(EntityType::Ole2Frame(frame));
|
let handle = self.add_entity(EntityType::Ole2Frame(Box::new(frame)));
|
||||||
if handle.is_null() {
|
if handle.is_null() {
|
||||||
return Err("the picture frame could not be added".into());
|
return Err("the picture frame could not be added".into());
|
||||||
}
|
}
|
||||||
@@ -6708,7 +6708,7 @@ mod tests {
|
|||||||
let EntityType::Dimension(dimension) = &mut after else {
|
let EntityType::Dimension(dimension) = &mut after else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
if let codec::entities::Dimension::Linear(value) = dimension {
|
if let codec::entities::Dimension::Linear(value) = &mut **dimension {
|
||||||
value.second_point.x = 30.0;
|
value.second_point.x = 30.0;
|
||||||
}
|
}
|
||||||
ocs_plugin_api::entity_coverage::validate_entity_mutation(&before, &after).unwrap();
|
ocs_plugin_api::entity_coverage::validate_entity_mutation(&before, &after).unwrap();
|
||||||
@@ -7414,7 +7414,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let mut viewport = codec::entities::Viewport::new();
|
let mut viewport = codec::entities::Viewport::new();
|
||||||
viewport.common.owner_handle = owner;
|
viewport.common.owner_handle = owner;
|
||||||
let viewport_handle = host.add_entity(EntityType::Viewport(viewport));
|
let viewport_handle = host.add_entity(EntityType::Viewport(Box::new(viewport)));
|
||||||
let scale_handle = host.document_mut().allocate_handle();
|
let scale_handle = host.document_mut().allocate_handle();
|
||||||
let mut scale = codec::objects::Scale::new("1:1", 1.0, 1.0);
|
let mut scale = codec::objects::Scale::new("1:1", 1.0, 1.0);
|
||||||
scale.handle = scale_handle;
|
scale.handle = scale_handle;
|
||||||
@@ -10861,7 +10861,7 @@ mod tests {
|
|||||||
bare.height = 30.0;
|
bare.height = 30.0;
|
||||||
let bare = host
|
let bare = host
|
||||||
.document_mut()
|
.document_mut()
|
||||||
.add_entity(EntityType::Viewport(bare))
|
.add_entity(EntityType::Viewport(Box::new(bare)))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
host.document().get_entity(bare).map(|e| match e {
|
host.document().get_entity(bare).map(|e| match e {
|
||||||
|
|||||||
+37
-33
@@ -1489,12 +1489,14 @@ impl OpenCADStudio {
|
|||||||
if let Some((anno_field, insert_after)) = anno {
|
if let Some((anno_field, insert_after)) = anno {
|
||||||
let is_anno = crate::scene::annotative::is_annotative(doc, entity)
|
let is_anno = crate::scene::annotative::is_annotative(doc, entity)
|
||||||
|| match entity {
|
|| match entity {
|
||||||
codec::EntityType::Dimension(codec::entities::Dimension::Arc(
|
codec::EntityType::Dimension(dimension)
|
||||||
dimension,
|
if matches!(**dimension, codec::entities::Dimension::Arc(_)) =>
|
||||||
)) => crate::scene::annotative::dim_style_is_annotative(
|
{
|
||||||
doc,
|
crate::scene::annotative::dim_style_is_annotative(
|
||||||
&dimension.base.style_name,
|
doc,
|
||||||
),
|
&dimension.base().style_name,
|
||||||
|
)
|
||||||
|
}
|
||||||
codec::EntityType::Tolerance(_) => {
|
codec::EntityType::Tolerance(_) => {
|
||||||
crate::scene::annotative::annotation_style_is_annotative(doc, entity)
|
crate::scene::annotative::annotation_style_is_annotative(doc, entity)
|
||||||
}
|
}
|
||||||
@@ -1530,7 +1532,9 @@ impl OpenCADStudio {
|
|||||||
"annotative",
|
"annotative",
|
||||||
yes_no_choice(t.is_annotative || is_anno),
|
yes_no_choice(t.is_annotative || is_anno),
|
||||||
),
|
),
|
||||||
codec::EntityType::Dimension(codec::entities::Dimension::Arc(_)) => {
|
codec::EntityType::Dimension(dimension)
|
||||||
|
if matches!(**dimension, codec::entities::Dimension::Arc(_)) =>
|
||||||
|
{
|
||||||
set_row(
|
set_row(
|
||||||
&mut sections,
|
&mut sections,
|
||||||
"annotative",
|
"annotative",
|
||||||
@@ -1683,10 +1687,14 @@ impl OpenCADStudio {
|
|||||||
format!("{} ({})", t!("Surface"), t!("Extrusion"))
|
format!("{} ({})", t!("Surface"), t!("Extrusion"))
|
||||||
}
|
}
|
||||||
// The reference names an angular dimension by its kind.
|
// The reference names an angular dimension by its kind.
|
||||||
codec::EntityType::Dimension(codec::entities::Dimension::Angular2Ln(_)) => {
|
codec::EntityType::Dimension(dimension)
|
||||||
|
if matches!(**dimension, codec::entities::Dimension::Angular2Ln(_)) =>
|
||||||
|
{
|
||||||
t!("Angular Dimension").into_owned()
|
t!("Angular Dimension").into_owned()
|
||||||
}
|
}
|
||||||
codec::EntityType::Dimension(codec::entities::Dimension::Angular3Pt(_)) => {
|
codec::EntityType::Dimension(dimension)
|
||||||
|
if matches!(**dimension, codec::entities::Dimension::Angular3Pt(_)) =>
|
||||||
|
{
|
||||||
t!("3 Point Angular Dimension").into_owned()
|
t!("3 Point Angular Dimension").into_owned()
|
||||||
}
|
}
|
||||||
codec::EntityType::Underlay(underlay) => match underlay.underlay_type {
|
codec::EntityType::Underlay(underlay) => match underlay.underlay_type {
|
||||||
@@ -1719,22 +1727,14 @@ impl OpenCADStudio {
|
|||||||
title
|
title
|
||||||
} else {
|
} else {
|
||||||
use codec::entities::Dimension;
|
use codec::entities::Dimension;
|
||||||
match entity {
|
match crate::entities::dimension::as_dimension(entity) {
|
||||||
codec::EntityType::Dimension(Dimension::Aligned(_)) => {
|
Some(Dimension::Aligned(_)) => t!("Aligned Dimensional Constraint"),
|
||||||
t!("Aligned Dimensional Constraint")
|
Some(Dimension::Angular2Ln(_)) => t!("Angular Dimension (Dynamic)"),
|
||||||
}
|
Some(Dimension::Angular3Pt(_)) => {
|
||||||
codec::EntityType::Dimension(Dimension::Angular2Ln(_)) => {
|
|
||||||
t!("Angular Dimension (Dynamic)")
|
|
||||||
}
|
|
||||||
codec::EntityType::Dimension(Dimension::Angular3Pt(_)) => {
|
|
||||||
t!("3 Point Angular Dimension (Dynamic)")
|
t!("3 Point Angular Dimension (Dynamic)")
|
||||||
}
|
}
|
||||||
codec::EntityType::Dimension(Dimension::Radius(_)) => {
|
Some(Dimension::Radius(_)) => t!("Radius Dimensional Constraint"),
|
||||||
t!("Radius Dimensional Constraint")
|
Some(Dimension::Diameter(_)) => t!("Diameter Dimensional Constraint"),
|
||||||
}
|
|
||||||
codec::EntityType::Dimension(Dimension::Diameter(_)) => {
|
|
||||||
t!("Diameter Dimensional Constraint")
|
|
||||||
}
|
|
||||||
_ => t!("Linear Dimensional Constraint"),
|
_ => t!("Linear Dimensional Constraint"),
|
||||||
}
|
}
|
||||||
.into_owned()
|
.into_owned()
|
||||||
@@ -2743,7 +2743,7 @@ handles={handles_ms:.1} panel={:.1} ribbon={ribbon_ms:.1} tail={:.1} selected={}
|
|||||||
// scale are available.
|
// scale are available.
|
||||||
if let codec::EntityType::Dimension(dim) = contextual.as_ref() {
|
if let codec::EntityType::Dimension(dim) = contextual.as_ref() {
|
||||||
if matches!(
|
if matches!(
|
||||||
dim,
|
&**dim,
|
||||||
codec::entities::Dimension::Linear(_)
|
codec::entities::Dimension::Linear(_)
|
||||||
| codec::entities::Dimension::Aligned(_)
|
| codec::entities::Dimension::Aligned(_)
|
||||||
) && !dim.base().text_user_positioned
|
) && !dim.base().text_user_positioned
|
||||||
@@ -2780,13 +2780,17 @@ handles={handles_ms:.1} panel={:.1} ribbon={ribbon_ms:.1} tail={:.1} selected={}
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let dynamic_angle = match contextual.as_ref() {
|
let contextual_dimension =
|
||||||
codec::EntityType::Dimension(
|
crate::entities::dimension::as_dimension(contextual.as_ref());
|
||||||
dim @ (codec::entities::Dimension::Angular2Ln(_)
|
let dynamic_angle = contextual_dimension
|
||||||
| codec::entities::Dimension::Angular3Pt(_)),
|
.filter(|dim| {
|
||||||
) if self.tabs[i].scene.is_dynamic_dimension(handle) => Some(dim),
|
matches!(
|
||||||
_ => None,
|
dim,
|
||||||
};
|
codec::entities::Dimension::Angular2Ln(_)
|
||||||
|
| codec::entities::Dimension::Angular3Pt(_)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.filter(|_| self.tabs[i].scene.is_dynamic_dimension(handle));
|
||||||
if let Some(dim) = dynamic_angle {
|
if let Some(dim) = dynamic_angle {
|
||||||
// A dynamic angle shows a triangle at each end of its arc
|
// A dynamic angle shows a triangle at each end of its arc
|
||||||
// pointing away from it, and squares at the arc point and
|
// pointing away from it, and squares at the arc point and
|
||||||
@@ -3060,8 +3064,8 @@ handles={handles_ms:.1} panel={:.1} ribbon={ribbon_ms:.1} tail={:.1} selected={}
|
|||||||
) -> Option<Handle> {
|
) -> Option<Handle> {
|
||||||
let i = self.active_tab;
|
let i = self.active_tab;
|
||||||
let tracks_dimension_chain = matches!(
|
let tracks_dimension_chain = matches!(
|
||||||
&entity,
|
crate::entities::dimension::as_dimension(&entity),
|
||||||
codec::EntityType::Dimension(
|
Some(
|
||||||
codec::entities::Dimension::Linear(_)
|
codec::entities::Dimension::Linear(_)
|
||||||
| codec::entities::Dimension::Aligned(_)
|
| codec::entities::Dimension::Aligned(_)
|
||||||
| codec::entities::Dimension::Angular2Ln(_)
|
| codec::entities::Dimension::Angular2Ln(_)
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ fn fixture_dimension_reference(app: &mut OpenCADStudio) -> String {
|
|||||||
dimension.base.style_name = "BO_ARROWSTYLE".to_string();
|
dimension.base.style_name = "BO_ARROWSTYLE".to_string();
|
||||||
app.tabs[i]
|
app.tabs[i]
|
||||||
.scene
|
.scene
|
||||||
.add_entity(EntityType::Dimension(Dimension::Aligned(dimension)));
|
.add_entity(EntityType::Dimension(Box::new(Dimension::Aligned(dimension))));
|
||||||
name.to_string()
|
name.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,7 +244,7 @@ fn fixture_dimension_name_reference(app: &mut OpenCADStudio) -> String {
|
|||||||
dimension.base.style_name = "BO_ARROWNAMESTYLE".to_string();
|
dimension.base.style_name = "BO_ARROWNAMESTYLE".to_string();
|
||||||
app.tabs[i]
|
app.tabs[i]
|
||||||
.scene
|
.scene
|
||||||
.add_entity(EntityType::Dimension(Dimension::Aligned(dimension)));
|
.add_entity(EntityType::Dimension(Box::new(Dimension::Aligned(dimension))));
|
||||||
name.to_string()
|
name.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2913,9 +2913,12 @@ impl OpenCADStudio {
|
|||||||
&value,
|
&value,
|
||||||
);
|
);
|
||||||
if applied && field == "dim_text_inside" {
|
if applied && field == "dim_text_inside" {
|
||||||
if let Some(codec::EntityType::Dimension(
|
let radial = app.tabs[i]
|
||||||
codec::entities::Dimension::LargeRadial(dimension),
|
.scene
|
||||||
)) = app.tabs[i].scene.document.get_entity_mut(handle)
|
.document
|
||||||
|
.get_entity_mut(handle)
|
||||||
|
.and_then(crate::entities::dimension::as_dimension_mut);
|
||||||
|
if let Some(codec::entities::Dimension::LargeRadial(dimension)) = radial
|
||||||
{
|
{
|
||||||
dimension.base.text_user_positioned = false;
|
dimension.base.text_user_positioned = false;
|
||||||
}
|
}
|
||||||
@@ -4182,9 +4185,13 @@ impl OpenCADStudio {
|
|||||||
&val,
|
&val,
|
||||||
);
|
);
|
||||||
if applied && field == "dim_text_inside" {
|
if applied && field == "dim_text_inside" {
|
||||||
if let Some(codec::EntityType::Dimension(
|
if let Some(codec::entities::Dimension::LargeRadial(
|
||||||
codec::entities::Dimension::LargeRadial(dimension),
|
dimension,
|
||||||
)) = self.tabs[i].scene.document.get_entity_mut(handle)
|
)) = self.tabs[i]
|
||||||
|
.scene
|
||||||
|
.document
|
||||||
|
.get_entity_mut(handle)
|
||||||
|
.and_then(crate::entities::dimension::as_dimension_mut)
|
||||||
{
|
{
|
||||||
dimension.base.text_user_positioned = false;
|
dimension.base.text_user_positioned = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -886,7 +886,7 @@ impl OpenCADStudio {
|
|||||||
.filter(|br| dwg_picked.iter().any(|(key, _)| *key == br.handle.value()))
|
.filter(|br| dwg_picked.iter().any(|(key, _)| *key == br.handle.value()))
|
||||||
.map(|br| br.handle)
|
.map(|br| br.handle)
|
||||||
.collect();
|
.collect();
|
||||||
let (infos, _dropped) = crate::io::xref::resolve_xrefs_for_keys(
|
let infos = crate::io::xref::resolve_xrefs_for_keys(
|
||||||
&mut self.tabs[i].scene.document,
|
&mut self.tabs[i].scene.document,
|
||||||
&base_dir,
|
&base_dir,
|
||||||
&handles,
|
&handles,
|
||||||
@@ -1093,7 +1093,7 @@ impl OpenCADStudio {
|
|||||||
self.tabs[i].xref_unloaded.remove(key);
|
self.tabs[i].xref_unloaded.remove(key);
|
||||||
self.tabs[i].xref_stat_cache.remove(key);
|
self.tabs[i].xref_stat_cache.remove(key);
|
||||||
}
|
}
|
||||||
let (infos, _dropped) =
|
let infos =
|
||||||
crate::io::xref::resolve_xrefs(&mut self.tabs[i].scene.document, &base_dir);
|
crate::io::xref::resolve_xrefs(&mut self.tabs[i].scene.document, &base_dir);
|
||||||
let fresh = crate::io::xref::collect_entries_with_prev(
|
let fresh = crate::io::xref::collect_entries_with_prev(
|
||||||
&self.tabs[i].scene.document,
|
&self.tabs[i].scene.document,
|
||||||
|
|||||||
+2
-25
@@ -2053,34 +2053,13 @@ impl OpenCADStudio {
|
|||||||
.xrefs
|
.xrefs
|
||||||
.iter()
|
.iter()
|
||||||
.any(|item| item.status == crate::io::xref::XrefStatus::Failed);
|
.any(|item| item.status == crate::io::xref::XrefStatus::Failed);
|
||||||
let document_repaired = parser_errors_recovered
|
let document_repaired = parser_errors_recovered || reference_recovered;
|
||||||
|| reference_recovered
|
|
||||||
|| caches.corrupt_dropped > 0
|
|
||||||
|| caches.xref_dropped > 0;
|
|
||||||
let recovery_needed = document_repaired || reference_failed;
|
let recovery_needed = document_repaired || reference_failed;
|
||||||
let total_ms = open_started
|
let total_ms = open_started
|
||||||
.map(|started| started.elapsed().as_millis() as u32)
|
.map(|started| started.elapsed().as_millis() as u32)
|
||||||
.unwrap_or(0);
|
.unwrap_or(0);
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(crate::tf!("Opened \"{name}\" — {entity_count} entities").as_ref());
|
.push_output(crate::tf!("Opened \"{name}\" — {entity_count} entities").as_ref());
|
||||||
if caches.corrupt_dropped > 0 {
|
|
||||||
self.command_line.push_error(
|
|
||||||
crate::tf!(
|
|
||||||
"Warning: {} corrupt entities dropped (parser junk — bad normals / counts)",
|
|
||||||
caches.corrupt_dropped
|
|
||||||
)
|
|
||||||
.as_ref(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if caches.xref_dropped > 0 {
|
|
||||||
self.command_line.push_error(
|
|
||||||
crate::tf!(
|
|
||||||
"Warning: {} corrupt xref entities dropped",
|
|
||||||
caches.xref_dropped
|
|
||||||
)
|
|
||||||
.as_ref(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
for info in &caches.xrefs {
|
for info in &caches.xrefs {
|
||||||
match info.status {
|
match info.status {
|
||||||
crate::io::xref::XrefStatus::Loaded => {
|
crate::io::xref::XrefStatus::Loaded => {
|
||||||
@@ -2180,9 +2159,7 @@ impl OpenCADStudio {
|
|||||||
size_bytes,
|
size_bytes,
|
||||||
caches.source_sha256.clone(),
|
caches.source_sha256.clone(),
|
||||||
caches.read_stats.clone(),
|
caches.read_stats.clone(),
|
||||||
entity_count.saturating_add(caches.corrupt_dropped),
|
entity_count,
|
||||||
caches.corrupt_dropped,
|
|
||||||
caches.xref_dropped,
|
|
||||||
&caches.xrefs,
|
&caches.xrefs,
|
||||||
&doc.notifications,
|
&doc.notifications,
|
||||||
document_repaired,
|
document_repaired,
|
||||||
|
|||||||
@@ -1084,7 +1084,7 @@ mod tests {
|
|||||||
.document
|
.document
|
||||||
.entities()
|
.entities()
|
||||||
.filter_map(|entity| match entity {
|
.filter_map(|entity| match entity {
|
||||||
EntityType::Hatch(hatch) => Some(hatch),
|
EntityType::Hatch(hatch) => Some(&**hatch),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ fn fixture() -> (OpenCADStudio, Handle, ViewportFrame) {
|
|||||||
viewport.custom_scale = 0.1;
|
viewport.custom_scale = 0.1;
|
||||||
viewport.view_direction = Vector3::UNIT_Z;
|
viewport.view_direction = Vector3::UNIT_Z;
|
||||||
viewport.turn_on();
|
viewport.turn_on();
|
||||||
let viewport = scene.add_entity(EntityType::Viewport(viewport));
|
let viewport = scene.add_entity(EntityType::Viewport(Box::new(viewport)));
|
||||||
let frame = scene.viewport_frame(viewport).unwrap();
|
let frame = scene.viewport_frame(viewport).unwrap();
|
||||||
scene.document.header.dimension_associativity = 2;
|
scene.document.header.dimension_associativity = 2;
|
||||||
let i = app.active_tab;
|
let i = app.active_tab;
|
||||||
@@ -323,7 +323,7 @@ fn viewport_dimension_linear_aligned_and_radial_object_picks() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
preview_text(
|
preview_text(
|
||||||
&app,
|
&app,
|
||||||
&EntityType::Dimension(dimension(&app.tabs[i].scene.document).clone())
|
&EntityType::Dimension(Box::new(dimension(&app.tabs[i].scene.document).clone()))
|
||||||
),
|
),
|
||||||
value,
|
value,
|
||||||
"{name}"
|
"{name}"
|
||||||
@@ -361,7 +361,7 @@ fn viewport_dimension_angular_preserves_angle_without_length_factor() {
|
|||||||
let _ = app.feed_command(StepInput::Point(place));
|
let _ = app.feed_command(StepInput::Point(place));
|
||||||
let doc = &app.tabs[app.active_tab].scene.document;
|
let doc = &app.tabs[app.active_tab].scene.document;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
preview_text(&app, &EntityType::Dimension(dimension(doc).clone())),
|
preview_text(&app, &EntityType::Dimension(Box::new(dimension(doc).clone()))),
|
||||||
value
|
value
|
||||||
);
|
);
|
||||||
assert!((dimension(doc).measurement() - 90.0).abs() < 1e-5);
|
assert!((dimension(doc).measurement() - 90.0).abs() < 1e-5);
|
||||||
@@ -1461,9 +1461,9 @@ fn viewport_dimension_invalid_paths_leave_no_partial_association() {
|
|||||||
Vector3::new(55.0, 60.0, 0.0),
|
Vector3::new(55.0, 60.0, 0.0),
|
||||||
)));
|
)));
|
||||||
for (source, path) in [(model, vec![Handle::new(u64::MAX)]), (leaf, vec![root])] {
|
for (source, path) in [(model, vec![Handle::new(u64::MAX)]), (leaf, vec![root])] {
|
||||||
let dim = scene.add_entity(EntityType::Dimension(Dimension::Aligned(
|
let dim = scene.add_entity(EntityType::Dimension(Box::new(Dimension::Aligned(
|
||||||
DimensionAligned::new(Vector3::new(50.0, 50.0, 0.0), Vector3::new(55.0, 50.0, 0.0)),
|
DimensionAligned::new(Vector3::new(50.0, 50.0, 0.0), Vector3::new(55.0, 50.0, 0.0)),
|
||||||
)));
|
))));
|
||||||
let invalid = AcceptedSnap {
|
let invalid = AcceptedSnap {
|
||||||
paper_point: DVec3::new(50.0, 50.0, 0.0),
|
paper_point: DVec3::new(50.0, 50.0, 0.0),
|
||||||
model_point: DVec3::ZERO,
|
model_point: DVec3::ZERO,
|
||||||
|
|||||||
@@ -3248,7 +3248,7 @@ pub(crate) fn materialize_large_radial_text_position(
|
|||||||
let Some(EntityType::Dimension(dimension)) = document.get_entity(handle) else {
|
let Some(EntityType::Dimension(dimension)) = document.get_entity(handle) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if !matches!(dimension, Dimension::LargeRadial(_)) || dimension.base().text_user_positioned {
|
if !matches!(&**dimension, Dimension::LargeRadial(_)) || dimension.base().text_user_positioned {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let source = document.dim_styles.iter().find(|style| {
|
let source = document.dim_styles.iter().find(|style| {
|
||||||
@@ -3262,8 +3262,8 @@ pub(crate) fn materialize_large_radial_text_position(
|
|||||||
.map(|style| resolved_dimension_style(style, dimension, document))
|
.map(|style| resolved_dimension_style(style, dimension, document))
|
||||||
.map(|style| styled_dimension_text_position(dimension, &style, 1.0))
|
.map(|style| styled_dimension_text_position(dimension, &style, 1.0))
|
||||||
.unwrap_or_else(|| dimension_text_pos_f64(dimension, None, 2.5, 1.0));
|
.unwrap_or_else(|| dimension_text_pos_f64(dimension, None, 2.5, 1.0));
|
||||||
if let Some(EntityType::Dimension(Dimension::LargeRadial(radial))) =
|
if let Some(Dimension::LargeRadial(radial)) =
|
||||||
document.get_entity_mut(handle)
|
document.get_entity_mut(handle).and_then(as_dimension_mut)
|
||||||
{
|
{
|
||||||
radial.base.text_middle_point = position;
|
radial.base.text_middle_point = position;
|
||||||
}
|
}
|
||||||
@@ -6491,7 +6491,7 @@ fn dimension_text_entity(
|
|||||||
}
|
}
|
||||||
mtext.normal = base.normal;
|
mtext.normal = base.normal;
|
||||||
mtext.common = base.common.clone();
|
mtext.common = base.common.clone();
|
||||||
return Some(EntityType::MText(mtext));
|
return Some(EntityType::MText(Box::new(mtext)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let value = if style.is_some_and(|style| style.dimtxtdirection) {
|
let value = if style.is_some_and(|style| style.dimtxtdirection) {
|
||||||
@@ -7150,7 +7150,7 @@ fn dimension_tolerance_entity(
|
|||||||
mtext.style = primary_style;
|
mtext.style = primary_style;
|
||||||
mtext.attachment_point = codec::entities::AttachmentPoint::MiddleCenter;
|
mtext.attachment_point = codec::entities::AttachmentPoint::MiddleCenter;
|
||||||
mtext.common = primary_common;
|
mtext.common = primary_common;
|
||||||
return Some(EntityType::MText(mtext));
|
return Some(EntityType::MText(Box::new(mtext)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut t = Text::with_value(tol, pos)
|
let mut t = Text::with_value(tol, pos)
|
||||||
@@ -9559,3 +9559,22 @@ mod layout_parity_tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The dimension an entity is, if it is one. The variant holds it boxed, so
|
||||||
|
/// a pattern cannot reach into it; match on this instead.
|
||||||
|
pub(crate) fn as_dimension(entity: &codec::EntityType) -> Option<&codec::entities::Dimension> {
|
||||||
|
match entity {
|
||||||
|
codec::EntityType::Dimension(dimension) => Some(dimension),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`as_dimension`], mutably.
|
||||||
|
pub(crate) fn as_dimension_mut(
|
||||||
|
entity: &mut codec::EntityType,
|
||||||
|
) -> Option<&mut codec::entities::Dimension> {
|
||||||
|
match entity {
|
||||||
|
codec::EntityType::Dimension(dimension) => Some(dimension),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -620,7 +620,7 @@ fn dynamic_data_text(data: &DynamicBlockData) -> String {
|
|||||||
"{}; dependencies {}; parameters {}; distance multiplier {:.6}; angle {:.6}",
|
"{}; dependencies {}; parameters {}; distance multiplier {:.6}; angle {:.6}",
|
||||||
value.action.element.name,
|
value.action.element.name,
|
||||||
value.action.dependencies.len(),
|
value.action.dependencies.len(),
|
||||||
value.action.parameter_ids.len(),
|
value.action.action_ids.len(),
|
||||||
value.offsets.distance_multiplier,
|
value.offsets.distance_multiplier,
|
||||||
value.offsets.angle_offset
|
value.offsets.angle_offset
|
||||||
),
|
),
|
||||||
@@ -628,14 +628,14 @@ fn dynamic_data_text(data: &DynamicBlockData) -> String {
|
|||||||
"{}; dependencies {}; parameters {}; connections {}",
|
"{}; dependencies {}; parameters {}; connections {}",
|
||||||
value.action.element.name,
|
value.action.element.name,
|
||||||
value.action.dependencies.len(),
|
value.action.dependencies.len(),
|
||||||
value.action.parameter_ids.len(),
|
value.action.action_ids.len(),
|
||||||
value.connections.len()
|
value.connections.len()
|
||||||
),
|
),
|
||||||
DynamicBlockData::RotateAction(value) | DynamicBlockData::ScaleAction(value) => format!(
|
DynamicBlockData::RotateAction(value) | DynamicBlockData::ScaleAction(value) => format!(
|
||||||
"{}; dependencies {}; parameters {}; base {:.6},{:.6},{:.6}; dependent {}",
|
"{}; dependencies {}; parameters {}; base {:.6},{:.6},{:.6}; dependent {}",
|
||||||
value.action.action.element.name,
|
value.action.action.element.name,
|
||||||
value.action.action.dependencies.len(),
|
value.action.action.dependencies.len(),
|
||||||
value.action.action.parameter_ids.len(),
|
value.action.action.action_ids.len(),
|
||||||
value.action.base_point.x,
|
value.action.base_point.x,
|
||||||
value.action.base_point.y,
|
value.action.base_point.y,
|
||||||
value.action.base_point.z,
|
value.action.base_point.z,
|
||||||
|
|||||||
@@ -676,7 +676,9 @@ pub fn adapt_mtext_paragraphs(
|
|||||||
ATab::Left(_) => TabKind::Left,
|
ATab::Left(_) => TabKind::Left,
|
||||||
ATab::Center(_) => TabKind::Center,
|
ATab::Center(_) => TabKind::Center,
|
||||||
ATab::Right(_) => TabKind::Right,
|
ATab::Right(_) => TabKind::Right,
|
||||||
ATab::Decimal(..) => TabKind::Decimal,
|
ATab::Decimal(..) | ATab::DecimalWithCharacter { .. } => {
|
||||||
|
TabKind::Decimal
|
||||||
|
}
|
||||||
};
|
};
|
||||||
TabStop {
|
TabStop {
|
||||||
position: ts.position() as f32 * entity_height,
|
position: ts.position() as f32 * entity_height,
|
||||||
|
|||||||
@@ -158,6 +158,16 @@ pub trait TextContent {
|
|||||||
fn replace_text(&mut self, search: &str, rep: &str);
|
fn replace_text(&mut self, search: &str, rep: &str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Entity variants holding their entity boxed (MTEXT) dispatch through here.
|
||||||
|
impl<T: TextContent + ?Sized> TextContent for Box<T> {
|
||||||
|
fn text_content(&self) -> Option<String> {
|
||||||
|
(**self).text_content()
|
||||||
|
}
|
||||||
|
fn replace_text(&mut self, search: &str, rep: &str) {
|
||||||
|
(**self).replace_text(search, rep)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Human-readable variant name used by Quick Select / Select Similar
|
/// Human-readable variant name used by Quick Select / Select Similar
|
||||||
/// filtering. Stable across releases — the strings here are the canonical
|
/// filtering. Stable across releases — the strings here are the canonical
|
||||||
/// type identifiers throughout the UI.
|
/// type identifiers throughout the UI.
|
||||||
|
|||||||
@@ -638,7 +638,7 @@ pub(crate) fn build_entity(
|
|||||||
if let Some(style) = text_style_field(spec, document)? {
|
if let Some(style) = text_style_field(spec, document)? {
|
||||||
mtext.style = style;
|
mtext.style = style;
|
||||||
}
|
}
|
||||||
EntityType::MText(mtext)
|
EntityType::MText(Box::new(mtext))
|
||||||
}
|
}
|
||||||
"INSERT" => {
|
"INSERT" => {
|
||||||
let block = spec["block"].as_str().unwrap_or("");
|
let block = spec["block"].as_str().unwrap_or("");
|
||||||
@@ -724,7 +724,7 @@ pub(crate) fn build_entity(
|
|||||||
let mut path = BoundaryPath::external();
|
let mut path = BoundaryPath::external();
|
||||||
path.add_edge(BoundaryEdge::Polyline(PolylineEdge::new(vertices, true)));
|
path.add_edge(BoundaryEdge::Polyline(PolylineEdge::new(vertices, true)));
|
||||||
hatch.paths.push(path);
|
hatch.paths.push(path);
|
||||||
EntityType::Hatch(hatch)
|
EntityType::Hatch(Box::new(hatch))
|
||||||
}
|
}
|
||||||
other => {
|
other => {
|
||||||
return Err(failure(
|
return Err(failure(
|
||||||
|
|||||||
@@ -472,6 +472,7 @@ fn complex_elements(
|
|||||||
scale: decimal(*scale),
|
scale: decimal(*scale),
|
||||||
rotation: decimal(*rot_deg).to_radians(),
|
rotation: decimal(*rot_deg).to_radians(),
|
||||||
absolute_rotation: false,
|
absolute_rotation: false,
|
||||||
|
source_flags: 0,
|
||||||
offset: [decimal(*x), decimal(*y)],
|
offset: [decimal(*x), decimal(*y)],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -492,6 +493,7 @@ fn complex_elements(
|
|||||||
scale: decimal(*scale),
|
scale: decimal(*scale),
|
||||||
rotation: decimal(*rot_deg).to_radians(),
|
rotation: decimal(*rot_deg).to_radians(),
|
||||||
absolute_rotation: false,
|
absolute_rotation: false,
|
||||||
|
source_flags: 0,
|
||||||
offset: [decimal(*x), decimal(*y)],
|
offset: [decimal(*x), decimal(*y)],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
+34
-408
@@ -130,7 +130,7 @@ fn recovery_fingerprint_needed(caches: &DerivedCaches) -> bool {
|
|||||||
crate::io::xref::XrefStatus::Recovered | crate::io::xref::XrefStatus::Failed
|
crate::io::xref::XrefStatus::Recovered | crate::io::xref::XrefStatus::Failed
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
parser_issue || caches.corrupt_dropped > 0 || caches.xref_dropped > 0 || reference_issue
|
parser_issue || reference_issue
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@@ -439,17 +439,10 @@ async fn open_path_with_phase_attempt(
|
|||||||
let parse_ms = t_parse.elapsed().as_millis() as u32;
|
let parse_ms = t_parse.elapsed().as_millis() as u32;
|
||||||
progress2.set(crate::app::OPEN_PHASE_PARSING, 5800, 1000, 1000);
|
progress2.set(crate::app::OPEN_PHASE_PARSING, 5800, 1000, 1000);
|
||||||
let t_purge = Instant::now();
|
let t_purge = Instant::now();
|
||||||
let dropped = purge_corrupt_entities(&mut doc);
|
if matches!(attempt, OpenAttempt::Recovery(..)) {
|
||||||
let purge_ms = t_purge.elapsed().as_millis() as u32;
|
repair_drawing(&mut doc);
|
||||||
if matches!(attempt, OpenAttempt::Strict) && dropped > 0 {
|
|
||||||
return Err(OpenAttemptFailure {
|
|
||||||
message: format!(
|
|
||||||
"normal read found {dropped} structurally invalid drawing records"
|
|
||||||
),
|
|
||||||
read_stats: Some(read_stats),
|
|
||||||
recoverable: true,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
let purge_ms = t_purge.elapsed().as_millis() as u32;
|
||||||
// Before the geometry is prepared below: repairing the
|
// Before the geometry is prepared below: repairing the
|
||||||
// drawing's stripped catalog linetypes after it would leave
|
// drawing's stripped catalog linetypes after it would leave
|
||||||
// the first view drawn without their shapes. None is added:
|
// the first view drawn without their shapes. None is added:
|
||||||
@@ -457,7 +450,7 @@ async fn open_path_with_phase_attempt(
|
|||||||
crate::io::linetypes::repair_document(&mut doc);
|
crate::io::linetypes::repair_document(&mut doc);
|
||||||
progress2.set(crate::app::OPEN_PHASE_XREF, 6000, 0, 1);
|
progress2.set(crate::app::OPEN_PHASE_XREF, 6000, 0, 1);
|
||||||
let t_xref = Instant::now();
|
let t_xref = Instant::now();
|
||||||
let (xref_infos, xref_dropped) = if let Some(base_dir) = path2.parent() {
|
let xref_infos = if let Some(base_dir) = path2.parent() {
|
||||||
let xref_progress = {
|
let xref_progress = {
|
||||||
let progress = Arc::clone(&progress2);
|
let progress = Arc::clone(&progress2);
|
||||||
let callback: Arc<dyn Fn(usize, usize) + Send + Sync> =
|
let callback: Arc<dyn Fn(usize, usize) + Send + Sync> =
|
||||||
@@ -479,7 +472,7 @@ async fn open_path_with_phase_attempt(
|
|||||||
Some(xref_progress),
|
Some(xref_progress),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
(Vec::new(), 0)
|
Vec::new()
|
||||||
};
|
};
|
||||||
let xref_ms = t_xref.elapsed().as_millis() as u32;
|
let xref_ms = t_xref.elapsed().as_millis() as u32;
|
||||||
progress2.set(crate::app::OPEN_PHASE_CACHING, 7400, 0, 10000);
|
progress2.set(crate::app::OPEN_PHASE_CACHING, 7400, 0, 10000);
|
||||||
@@ -506,9 +499,7 @@ async fn open_path_with_phase_attempt(
|
|||||||
// Filled in after `prepare_open_geometry` below.
|
// Filled in after `prepare_open_geometry` below.
|
||||||
finalize_ms: 0,
|
finalize_ms: 0,
|
||||||
};
|
};
|
||||||
caches.corrupt_dropped = dropped;
|
|
||||||
caches.read_stats = Some(read_stats);
|
caches.read_stats = Some(read_stats);
|
||||||
caches.xref_dropped = xref_dropped;
|
|
||||||
caches.xrefs = xref_infos;
|
caches.xrefs = xref_infos;
|
||||||
if recovery_fingerprint_needed(&caches) {
|
if recovery_fingerprint_needed(&caches) {
|
||||||
caches.source_sha256 =
|
caches.source_sha256 =
|
||||||
@@ -800,25 +791,17 @@ async fn load_web_bytes(
|
|||||||
fix_current_style_names(&mut doc);
|
fix_current_style_names(&mut doc);
|
||||||
crate::entities::field::local_header_dates(&mut doc);
|
crate::entities::field::local_header_dates(&mut doc);
|
||||||
progress.set(crate::app::OPEN_PHASE_CACHING, 7000, 0, 1);
|
progress.set(crate::app::OPEN_PHASE_CACHING, 7000, 0, 1);
|
||||||
let dropped = purge_corrupt_entities(&mut doc);
|
if recovery_mode {
|
||||||
if !recovery_mode && dropped > 0 {
|
repair_drawing(&mut doc);
|
||||||
return Err(OpenLoadError {
|
|
||||||
message: format!("normal read found {dropped} structurally invalid drawing records"),
|
|
||||||
source_sha256: None,
|
|
||||||
read_stats: Some(outcome.stats),
|
|
||||||
recovery_available: true,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
// XREFs inside the opened drawing resolve from the in-session bytes
|
// XREFs inside the opened drawing resolve from the in-session bytes
|
||||||
// registry (see `resolve_web_xrefs`) before the caches snapshot the
|
// registry (see `resolve_web_xrefs`) before the caches snapshot the
|
||||||
// document, so merged xref geometry is part of the caches — the same
|
// document, so merged xref geometry is part of the caches — the same
|
||||||
// phase order the native open uses.
|
// phase order the native open uses.
|
||||||
let (xref_infos, xref_dropped) = resolve_web_xrefs(&mut doc, progress.clone()).await;
|
let xref_infos = resolve_web_xrefs(&mut doc, progress.clone()).await;
|
||||||
let mut caches = crate::scene::build_derived_caches(&doc);
|
let mut caches = crate::scene::build_derived_caches(&doc);
|
||||||
caches.corrupt_dropped = dropped;
|
|
||||||
caches.read_stats = Some(outcome.stats);
|
caches.read_stats = Some(outcome.stats);
|
||||||
caches.xrefs = xref_infos;
|
caches.xrefs = xref_infos;
|
||||||
caches.xref_dropped = xref_dropped;
|
|
||||||
if source_sha256.is_none() && recovery_fingerprint_needed(&caches) {
|
if source_sha256.is_none() && recovery_fingerprint_needed(&caches) {
|
||||||
source_sha256 = web_worker::sha256_document(bytes).await.ok();
|
source_sha256 = web_worker::sha256_document(bytes).await.ok();
|
||||||
}
|
}
|
||||||
@@ -891,7 +874,7 @@ pub async fn parse_drawing_bytes_web(name: &str, bytes: &[u8]) -> Result<CadDocu
|
|||||||
async fn resolve_web_xrefs(
|
async fn resolve_web_xrefs(
|
||||||
doc: &mut CadDocument,
|
doc: &mut CadDocument,
|
||||||
progress: Arc<OpenProgressState>,
|
progress: Arc<OpenProgressState>,
|
||||||
) -> (Vec<crate::io::xref::XrefInfo>, usize) {
|
) -> Vec<crate::io::xref::XrefInfo> {
|
||||||
let pending: Vec<String> = doc
|
let pending: Vec<String> = doc
|
||||||
.block_records
|
.block_records
|
||||||
.iter()
|
.iter()
|
||||||
@@ -995,7 +978,7 @@ pub fn load_bytes(name: &str, bytes: Vec<u8>) -> Result<CadDocument, String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
pub fn load_bytes_finalized(path: &Path, bytes: Vec<u8>) -> Result<(CadDocument, usize), String> {
|
pub fn load_bytes_finalized(path: &Path, bytes: Vec<u8>) -> Result<CadDocument, String> {
|
||||||
let name = path
|
let name = path
|
||||||
.file_name()
|
.file_name()
|
||||||
.map(|n| n.to_string_lossy().into_owned())
|
.map(|n| n.to_string_lossy().into_owned())
|
||||||
@@ -1006,8 +989,7 @@ pub fn load_bytes_finalized(path: &Path, bytes: Vec<u8>) -> Result<(CadDocument,
|
|||||||
doc.source_path = Some(path.to_string_lossy().into_owned());
|
doc.source_path = Some(path.to_string_lossy().into_owned());
|
||||||
// Opening is a field evaluation event (FIELDEVAL bit 1).
|
// Opening is a field evaluation event (FIELDEVAL bit 1).
|
||||||
crate::entities::field::update_fields(&mut doc, 1, None);
|
crate::entities::field::update_fields(&mut doc, 1, None);
|
||||||
let dropped = purge_corrupt_entities(&mut doc);
|
Ok(doc)
|
||||||
Ok((doc, dropped))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load a DWG or DXF file directly from a path (auto-detect by extension).
|
/// Load a DWG or DXF file directly from a path (auto-detect by extension).
|
||||||
@@ -1254,7 +1236,6 @@ fn finalize_loaded_outcome(
|
|||||||
let doc = &mut outcome.document;
|
let doc = &mut outcome.document;
|
||||||
normalize_block_origins(doc);
|
normalize_block_origins(doc);
|
||||||
materialize_missing_block_markers(doc);
|
materialize_missing_block_markers(doc);
|
||||||
normalize_knotless_splines(doc);
|
|
||||||
if outcome.stats.source_format == Some(codec::SourceFormat::Dxf) {
|
if outcome.stats.source_format == Some(codec::SourceFormat::Dxf) {
|
||||||
fix_dxf_dimension_rotations(doc);
|
fix_dxf_dimension_rotations(doc);
|
||||||
fix_dxf_layout_plot_settings(doc);
|
fix_dxf_layout_plot_settings(doc);
|
||||||
@@ -2679,174 +2660,24 @@ fn sync_current_styles_on_save(doc: &mut CadDocument) {
|
|||||||
set_sketch_settings(doc, sketch_type, increment, tolerance);
|
set_sketch_settings(doc, sketch_type, increment, tolerance);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Corrupt-entity guard ──────────────────────────────────────────────────
|
/// Recovery runs the codec's repair and reports what it did, and what it
|
||||||
//
|
/// left, through the drawing's notifications.
|
||||||
// opencadcodec's DWG parser occasionally desynchronises on certain files and
|
pub(crate) fn repair_drawing(doc: &mut CadDocument) {
|
||||||
// produces entities with garbage fields: non-unit normals (components in
|
let repair = doc.repair();
|
||||||
// 1e200+), nonsensical vertex counts (e.g. 100000), or infinite/NaN
|
for action in &repair.actions {
|
||||||
// coordinates. Tessellating such entities triggers huge allocations and
|
doc.notifications.notify(
|
||||||
// numerical blow-ups in the wire pipeline.
|
codec::notification::NotificationType::Warning,
|
||||||
//
|
format!("Recovery repair: {action:?}"),
|
||||||
// `purge_corrupt_entities` scans the document and removes any entity that
|
);
|
||||||
// fails a cheap sanity check, returning the number dropped so the caller can
|
|
||||||
// surface it to the UI / log.
|
|
||||||
//
|
|
||||||
// Keep valid degenerate geometry: dropping it would trigger strict-open recovery.
|
|
||||||
|
|
||||||
fn finite_unit_normal(n: &codec::types::Vector3) -> bool {
|
|
||||||
let (x, y, z) = (n.x, n.y, n.z);
|
|
||||||
if !x.is_finite() || !y.is_finite() || !z.is_finite() {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
let mag2 = x * x + y * y + z * z;
|
for issue in &repair.unresolved {
|
||||||
// Accept anything within ~10% of unit length. Real files sometimes
|
doc.notifications.notify(
|
||||||
// store slightly denormalised normals from rounding.
|
codec::notification::NotificationType::Warning,
|
||||||
(mag2 - 1.0).abs() < 0.21
|
format!("Recovery left unresolved: {}", issue.message),
|
||||||
}
|
);
|
||||||
|
|
||||||
fn finite_coord(v: f64) -> bool {
|
|
||||||
v.is_finite() && v.abs() < 1.0e12
|
|
||||||
}
|
|
||||||
|
|
||||||
fn finite_vec3(v: &codec::types::Vector3) -> bool {
|
|
||||||
finite_coord(v.x) && finite_coord(v.y) && finite_coord(v.z)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if the entity looks like parser garbage and should be dropped.
|
|
||||||
pub(crate) fn is_entity_corrupt(e: &EntityType) -> bool {
|
|
||||||
use codec::entities::EntityType as E;
|
|
||||||
// Reject polylines at or above this vertex count. Even valid drawings
|
|
||||||
// rarely use this many — and parser desync produces exactly-100_000-vertex
|
|
||||||
// junk records.
|
|
||||||
const MAX_VERTS: usize = 100_000;
|
|
||||||
match e {
|
|
||||||
E::LwPolyline(p) => {
|
|
||||||
!finite_unit_normal(&p.normal)
|
|
||||||
|| p.vertices.len() >= MAX_VERTS
|
|
||||||
|| !finite_coord(p.elevation)
|
|
||||||
|| p.elevation.abs() > 1.0e10
|
|
||||||
|| !finite_coord(p.thickness)
|
|
||||||
|| p.thickness.abs() > 1.0e10
|
|
||||||
|| p.vertices
|
|
||||||
.iter()
|
|
||||||
.any(|v| !finite_coord(v.location.x) || !finite_coord(v.location.y))
|
|
||||||
}
|
|
||||||
E::Polyline2D(p) => {
|
|
||||||
!finite_unit_normal(&p.normal)
|
|
||||||
|| p.vertices.len() >= MAX_VERTS
|
|
||||||
|| !finite_coord(p.elevation)
|
|
||||||
|| p.elevation.abs() > 1.0e10
|
|
||||||
|| !finite_coord(p.thickness)
|
|
||||||
|| p.thickness.abs() > 1.0e10
|
|
||||||
|| p.vertices.iter().any(|v| !finite_vec3(&v.location))
|
|
||||||
}
|
|
||||||
E::Polyline3D(p) => {
|
|
||||||
p.vertices.len() >= MAX_VERTS || p.vertices.iter().any(|v| !finite_vec3(&v.position))
|
|
||||||
}
|
|
||||||
E::Polyline(p) => {
|
|
||||||
p.vertices.len() >= MAX_VERTS || p.vertices.iter().any(|v| !finite_vec3(&v.location))
|
|
||||||
}
|
|
||||||
E::Line(l) => !finite_vec3(&l.start) || !finite_vec3(&l.end),
|
|
||||||
// Zero-radius curves are valid and have bounded kernel tessellation.
|
|
||||||
E::Circle(c) => {
|
|
||||||
!finite_vec3(&c.center) || !finite_coord(c.radius) || c.radius.abs() > 1.0e10
|
|
||||||
}
|
|
||||||
E::Arc(a) => {
|
|
||||||
!finite_vec3(&a.center)
|
|
||||||
|| !finite_coord(a.radius)
|
|
||||||
|| !a.start_angle.is_finite()
|
|
||||||
|| !a.end_angle.is_finite()
|
|
||||||
|| a.radius.abs() > 1.0e10
|
|
||||||
|| !finite_unit_normal(&a.normal)
|
|
||||||
}
|
|
||||||
E::Ellipse(e) => {
|
|
||||||
!finite_vec3(&e.center)
|
|
||||||
|| !finite_vec3(&e.major_axis)
|
|
||||||
|| !e.start_parameter.is_finite()
|
|
||||||
|| !e.end_parameter.is_finite()
|
|
||||||
|| (e.end_parameter - e.start_parameter).abs() < 1.0e-9
|
|
||||||
|| {
|
|
||||||
let m2 = e.major_axis.x * e.major_axis.x
|
|
||||||
+ e.major_axis.y * e.major_axis.y
|
|
||||||
+ e.major_axis.z * e.major_axis.z;
|
|
||||||
!m2.is_finite() || m2 < 1.0e-20 || m2 > 1.0e20
|
|
||||||
}
|
|
||||||
|| !e.minor_axis_ratio.is_finite()
|
|
||||||
|| e.minor_axis_ratio.abs() < 1.0e-10
|
|
||||||
}
|
|
||||||
E::Spline(s) => {
|
|
||||||
// Parser desync emits exactly-100_000-control-point splines with a
|
|
||||||
// garbage knot vector. Building a NURBS from one and
|
|
||||||
// tessellating it runs `parameter_division` into an unbounded
|
|
||||||
// allocation — single-threaded, 32 GB+ — long before the drawing
|
|
||||||
// finishes loading. Reject the desync signature plus any spline
|
|
||||||
// the kernel can't build: non-finite control points, or a knot vector
|
|
||||||
// that's non-finite, non-monotonic, or the wrong length
|
|
||||||
// (the kernel requires `knots.len() == ctrl.len() + degree + 1`).
|
|
||||||
let n = s.control_points.len();
|
|
||||||
let degree_bad = s.degree < 1;
|
|
||||||
let deg = s.degree.max(0) as usize;
|
|
||||||
let compact_periodic_knots = s.flags.periodic && s.knots.len() == n.saturating_add(1);
|
|
||||||
let knots_bad = !s.knots.is_empty()
|
|
||||||
&& (s.knots.iter().any(|k| !k.is_finite())
|
|
||||||
|| s.knots.windows(2).any(|w| w[1] < w[0])
|
|
||||||
|| (!compact_periodic_knots && s.knots.len() != n + deg + 1));
|
|
||||||
// A single control point with no knots and no fit points cannot
|
|
||||||
// form a curve, and no knot vector exists for it.
|
|
||||||
let lone_point = n == 1 && s.knots.is_empty() && s.fit_points.is_empty();
|
|
||||||
n >= MAX_VERTS
|
|
||||||
|| degree_bad
|
|
||||||
|| lone_point
|
|
||||||
|| s.control_points.iter().any(|p| !finite_vec3(p))
|
|
||||||
|| knots_bad
|
|
||||||
}
|
|
||||||
_ => false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Give control-point splines stored without knots a degree their control
|
|
||||||
/// points can carry, and the matching clamped knot vector.
|
|
||||||
///
|
|
||||||
/// A degree-p curve needs at least p + 1 control points. Knot generation
|
|
||||||
/// (here, and in the DWG writer for knot-less splines) subtracts in `usize`
|
|
||||||
/// and underflows when there are fewer; in release builds the wrapped count
|
|
||||||
/// drives an unbounded allocation. Lowering the degree keeps the geometry the
|
|
||||||
/// points describe: two points are a straight segment at any degree.
|
|
||||||
fn normalize_knotless_splines(doc: &mut CadDocument) {
|
|
||||||
for entity in doc.entities_mut() {
|
|
||||||
let EntityType::Spline(spline) = entity else {
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
let n = spline.control_points.len();
|
|
||||||
if !spline.knots.is_empty() || n < 2 || spline.degree < 1 {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let degree = (spline.degree as usize).min(n - 1);
|
|
||||||
spline.degree = degree as i32;
|
|
||||||
spline.knots = codec::entities::Spline::generate_clamped_knots(degree, n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn purge_corrupt_entities(doc: &mut CadDocument) -> usize {
|
|
||||||
use crate::par::prelude::*;
|
|
||||||
normalize_knotless_splines(doc);
|
|
||||||
// Detection is pure and read-only; the per-vertex finite/extent checks on
|
|
||||||
// large polylines dominate, so fan the scan out across cores. Gather
|
|
||||||
// entity references in one pass, test in parallel, then remove serially
|
|
||||||
// (`remove_entity` needs `&mut doc`).
|
|
||||||
let entities: Vec<&EntityType> = doc.entities().collect();
|
|
||||||
let bad: Vec<codec::Handle> = entities
|
|
||||||
.par_iter()
|
|
||||||
.filter(|e| is_entity_corrupt(e))
|
|
||||||
.map(|e| e.common().handle)
|
|
||||||
.collect();
|
|
||||||
let n = bad.len();
|
|
||||||
for h in bad {
|
|
||||||
doc.remove_entity(h);
|
|
||||||
}
|
|
||||||
n
|
|
||||||
}
|
|
||||||
|
|
||||||
/// opencadcodec's ViewportStatusFlags::from_bits() maps bit 0 → is_on and bit 15 → locked,
|
/// opencadcodec's ViewportStatusFlags::from_bits() maps bit 0 → is_on and bit 15 → locked,
|
||||||
/// but the real DXF/DWG spec uses bit 15 (0x8000) → viewport on and bit 14 (0x4000) → locked.
|
/// but the real DXF/DWG spec uses bit 15 (0x8000) → viewport on and bit 14 (0x4000) → locked.
|
||||||
/// Files from AutoCAD and other tools always set bit 15 for active viewports, leaving bit 0
|
/// Files from AutoCAD and other tools always set bit 15 for active viewports, leaving bit 0
|
||||||
@@ -2969,7 +2800,7 @@ mod dimension_arrow_save_tests {
|
|||||||
dimension.definition_point = Vector3::new(0.0, 20.0, 0.0);
|
dimension.definition_point = Vector3::new(0.0, 20.0, 0.0);
|
||||||
dimension.base.definition_point = dimension.definition_point;
|
dimension.base.definition_point = dimension.definition_point;
|
||||||
dimension.base.text_middle_point = Vector3::new(50.0, 20.0, 0.0);
|
dimension.base.text_middle_point = Vector3::new(50.0, 20.0, 0.0);
|
||||||
doc.add_entity(EntityType::Dimension(Dimension::Linear(dimension)))
|
doc.add_entity(EntityType::Dimension(Box::new(Dimension::Linear(dimension))))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
doc
|
doc
|
||||||
}
|
}
|
||||||
@@ -3161,214 +2992,6 @@ mod layer_roundtrip_tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod corrupt_guard_tests {
|
|
||||||
use super::*;
|
|
||||||
use codec::entities::{Arc, Circle, EntityType, Spline};
|
|
||||||
use codec::types::Vector3;
|
|
||||||
|
|
||||||
fn knotless_spline(degree: i32, points: usize) -> Spline {
|
|
||||||
let mut spline = Spline::new();
|
|
||||||
spline.degree = degree;
|
|
||||||
spline.control_points = (0..points)
|
|
||||||
.map(|index| Vector3::new(index as f64, index as f64, 0.0))
|
|
||||||
.collect();
|
|
||||||
spline
|
|
||||||
}
|
|
||||||
|
|
||||||
// Degree 3 over two control points with no knot vector: generating knots
|
|
||||||
// for it underflows, and writing it to DWG used to panic (debug) or
|
|
||||||
// allocate without bound (release).
|
|
||||||
#[test]
|
|
||||||
fn knotless_spline_with_too_few_points_is_lowered_and_saves_as_dwg() {
|
|
||||||
let mut doc = CadDocument::new();
|
|
||||||
doc.add_entity(EntityType::Spline(knotless_spline(3, 2)))
|
|
||||||
.unwrap();
|
|
||||||
doc.add_entity(EntityType::Spline(knotless_spline(3, 1)))
|
|
||||||
.unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
purge_corrupt_entities(&mut doc),
|
|
||||||
1,
|
|
||||||
"the lone point is dropped"
|
|
||||||
);
|
|
||||||
let spline = doc
|
|
||||||
.entities()
|
|
||||||
.find_map(|entity| match entity {
|
|
||||||
EntityType::Spline(spline) => Some(spline.clone()),
|
|
||||||
_ => None,
|
|
||||||
})
|
|
||||||
.expect("the two-point spline is kept");
|
|
||||||
assert_eq!(spline.degree, 1);
|
|
||||||
assert_eq!(spline.knots, vec![0.0, 0.0, 1.0, 1.0]);
|
|
||||||
|
|
||||||
let path =
|
|
||||||
std::env::temp_dir().join(format!("ocs_knotless_spline_{}.dwg", std::process::id()));
|
|
||||||
save_as_version(&doc, &path, codec::DxfVersion::AC1032).expect("save");
|
|
||||||
let _ = std::fs::remove_file(&path);
|
|
||||||
}
|
|
||||||
|
|
||||||
// `load_file` (headless export, xrefs, block import) does not purge, so
|
|
||||||
// the spline repair has to happen when any load is finalized.
|
|
||||||
#[test]
|
|
||||||
fn knotless_spline_is_repaired_by_every_load_path() {
|
|
||||||
const DXF: &str =
|
|
||||||
"0\nSECTION\n2\nENTITIES\n0\nSPLINE\n8\n0\n70\n0\n71\n3\n72\n0\n73\n2\n74\n0\n\
|
|
||||||
10\n0\n20\n0\n30\n0\n10\n1\n20\n1\n30\n0\n0\nENDSEC\n0\nEOF\n";
|
|
||||||
let dir = std::env::temp_dir();
|
|
||||||
let source = dir.join(format!("ocs_knotless_load_{}.dxf", std::process::id()));
|
|
||||||
let target = dir.join(format!("ocs_knotless_load_{}.dwg", std::process::id()));
|
|
||||||
std::fs::write(&source, DXF).unwrap();
|
|
||||||
let doc = load_file(&source).expect("load");
|
|
||||||
let _ = std::fs::remove_file(&source);
|
|
||||||
let spline = doc
|
|
||||||
.entities()
|
|
||||||
.find_map(|entity| match entity {
|
|
||||||
EntityType::Spline(spline) => Some(spline),
|
|
||||||
_ => None,
|
|
||||||
})
|
|
||||||
.expect("spline");
|
|
||||||
assert_eq!(spline.degree, 1);
|
|
||||||
assert_eq!(spline.knots.len(), 4);
|
|
||||||
save_as_version(&doc, &target, codec::DxfVersion::AC1032).expect("save");
|
|
||||||
let _ = std::fs::remove_file(&target);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Small but finite arcs are valid records. Kernel tessellation is bounded,
|
|
||||||
// so opening must retain them instead of treating their size as corruption.
|
|
||||||
#[test]
|
|
||||||
fn keeps_small_finite_arc() {
|
|
||||||
let mut a = Arc::new();
|
|
||||||
a.center = Vector3::new(2880.84, 891.83, 0.0);
|
|
||||||
a.radius = 0.0038974142851181423;
|
|
||||||
a.start_angle = 1.0401656235942365;
|
|
||||||
a.end_angle = 1.0401671831670538;
|
|
||||||
a.normal = Vector3::new(0.0, 0.0, 1.0);
|
|
||||||
assert!(!is_entity_corrupt(&EntityType::Arc(a)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// A nearly straight arc still carries valid source geometry.
|
|
||||||
#[test]
|
|
||||||
fn keeps_nearly_straight_arc() {
|
|
||||||
let mut a = Arc::new();
|
|
||||||
a.center = Vector3::new(551435.3071786845, 4051623.7156955916, 0.0);
|
|
||||||
a.radius = 35.0;
|
|
||||||
a.start_angle = 5.823361856481176;
|
|
||||||
a.end_angle = 5.823362506017916;
|
|
||||||
a.normal = Vector3::new(0.0, 0.0, 1.0);
|
|
||||||
assert!(!is_entity_corrupt(&EntityType::Arc(a)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// A large-radius small-sweep arc is still a visible curve and must survive:
|
|
||||||
// radius 1e6 × sweep 1e-4 ≈ 100 units of arc.
|
|
||||||
#[test]
|
|
||||||
fn keeps_large_radius_small_sweep_arc() {
|
|
||||||
let mut a = Arc::new();
|
|
||||||
a.radius = 1.0e6;
|
|
||||||
a.start_angle = 0.0;
|
|
||||||
a.end_angle = 1.0e-4;
|
|
||||||
a.normal = Vector3::new(0.0, 0.0, 1.0);
|
|
||||||
assert!(!is_entity_corrupt(&EntityType::Arc(a)));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn keeps_zero_radius_circle_and_arc() {
|
|
||||||
let mut c = Circle::new();
|
|
||||||
c.center = Vector3::new(206.2, 150.7, 0.0);
|
|
||||||
c.radius = 0.0;
|
|
||||||
assert!(!is_entity_corrupt(&EntityType::Circle(c)));
|
|
||||||
|
|
||||||
let mut a = Arc::new();
|
|
||||||
a.center = Vector3::new(223.5, 174.5, 0.0);
|
|
||||||
a.radius = 0.0;
|
|
||||||
a.start_angle = 0.0;
|
|
||||||
a.end_angle = 0.0;
|
|
||||||
a.normal = Vector3::new(0.0, 0.0, 1.0);
|
|
||||||
assert!(!is_entity_corrupt(&EntityType::Arc(a)));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn drops_absurd_radius_circle() {
|
|
||||||
let mut c = Circle::new();
|
|
||||||
c.radius = 1.0e11;
|
|
||||||
assert!(is_entity_corrupt(&EntityType::Circle(c)));
|
|
||||||
let mut c = Circle::new();
|
|
||||||
c.radius = f64::NAN;
|
|
||||||
assert!(is_entity_corrupt(&EntityType::Circle(c)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parser desync emits 100_000-control-point splines; building a kernel
|
|
||||||
// NURBS from one and tessellating it OOMs. The control-point cap rejects it.
|
|
||||||
#[test]
|
|
||||||
fn rejects_desync_spline() {
|
|
||||||
let pts = vec![Vector3::new(0.0, 0.0, 0.0); 100_000];
|
|
||||||
let s = Spline::from_control_points(3, pts);
|
|
||||||
assert!(is_entity_corrupt(&EntityType::Spline(s)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// A collapsed spline is still a valid source record. Kernel subdivision
|
|
||||||
// has a fixed depth bound and can process it safely.
|
|
||||||
#[test]
|
|
||||||
fn keeps_degenerate_point_spline() {
|
|
||||||
let pts = vec![Vector3::new(1e-12, -1e-12, 0.0); 9];
|
|
||||||
let s = Spline::from_control_points(3, pts);
|
|
||||||
assert!(!is_entity_corrupt(&EntityType::Spline(s)));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn keeps_compact_periodic_spline_knots() {
|
|
||||||
let pts = (0..12)
|
|
||||||
.map(|index| Vector3::new(index as f64, (index % 3) as f64, 0.0))
|
|
||||||
.collect();
|
|
||||||
let mut s = Spline::from_control_points(2, pts);
|
|
||||||
s.flags.closed = true;
|
|
||||||
s.flags.periodic = true;
|
|
||||||
s.knots = (0..13).map(|value| value as f64).collect();
|
|
||||||
assert!(!is_entity_corrupt(&EntityType::Spline(s)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// A normal cubic spline (4 control points, valid clamped knots) survives.
|
|
||||||
#[test]
|
|
||||||
fn keeps_valid_spline() {
|
|
||||||
let pts = vec![
|
|
||||||
Vector3::new(0.0, 0.0, 0.0),
|
|
||||||
Vector3::new(1.0, 1.0, 0.0),
|
|
||||||
Vector3::new(2.0, -1.0, 0.0),
|
|
||||||
Vector3::new(3.0, 0.0, 0.0),
|
|
||||||
];
|
|
||||||
let s = Spline::from_control_points(3, pts);
|
|
||||||
assert!(!is_entity_corrupt(&EntityType::Spline(s)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// A corrupt or adversarial MINSERT row/column pair (u16, so its unchecked
|
|
||||||
// product can reach into the billions) must be rejected before it can
|
|
||||||
// drive the render graph's per-instance allocation and expansion.
|
|
||||||
#[test]
|
|
||||||
fn preserves_large_minsert_data_while_rendering_is_bounded() {
|
|
||||||
let mut i = codec::entities::Insert::new("BLOCK", Vector3::ZERO);
|
|
||||||
i.row_count = u16::MAX;
|
|
||||||
i.column_count = u16::MAX;
|
|
||||||
assert!(!is_entity_corrupt(&EntityType::Insert(i)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// An ordinary array insert, well under the budget, is valid source data.
|
|
||||||
#[test]
|
|
||||||
fn keeps_a_reasonable_minsert() {
|
|
||||||
let mut i = codec::entities::Insert::new("BLOCK", Vector3::ZERO);
|
|
||||||
i.row_count = 10;
|
|
||||||
i.column_count = 10;
|
|
||||||
i.row_spacing = 5.0;
|
|
||||||
i.column_spacing = 5.0;
|
|
||||||
assert!(!is_entity_corrupt(&EntityType::Insert(i)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// A plain (non-array) INSERT is never treated as a MINSERT-count problem.
|
|
||||||
#[test]
|
|
||||||
fn keeps_a_plain_insert() {
|
|
||||||
let i = codec::entities::Insert::new("BLOCK", Vector3::ZERO);
|
|
||||||
assert!(!is_entity_corrupt(&EntityType::Insert(i)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod pre_r2000_layer_plot_tests {
|
mod pre_r2000_layer_plot_tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@@ -3545,11 +3168,12 @@ mod prepare_save_tests {
|
|||||||
dim.base.definition_point = Vector3::ZERO;
|
dim.base.definition_point = Vector3::ZERO;
|
||||||
dim.base.common.handle = doc.allocate_handle();
|
dim.base.common.handle = doc.allocate_handle();
|
||||||
let handle = dim.base.common.handle;
|
let handle = dim.base.common.handle;
|
||||||
doc.add_entity(EntityType::Dimension(Dimension::Linear(dim)))
|
doc.add_entity(EntityType::Dimension(Box::new(Dimension::Linear(dim))))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let prepared = prepare_document_for_save(doc.clone(), doc.version);
|
let prepared = prepare_document_for_save(doc.clone(), doc.version);
|
||||||
let EntityType::Dimension(Dimension::Linear(linear)) = prepared.get_entity(handle).unwrap()
|
let Some(Dimension::Linear(linear)) =
|
||||||
|
crate::entities::dimension::as_dimension(prepared.get_entity(handle).unwrap())
|
||||||
else {
|
else {
|
||||||
panic!("dimension missing from prepared clone");
|
panic!("dimension missing from prepared clone");
|
||||||
};
|
};
|
||||||
@@ -3565,7 +3189,9 @@ mod prepare_save_tests {
|
|||||||
assert_eq!(linear.base.definition_point, linear.definition_point);
|
assert_eq!(linear.base.definition_point, linear.definition_point);
|
||||||
|
|
||||||
// The live document is untouched: no block name, stale group-10.
|
// The live document is untouched: no block name, stale group-10.
|
||||||
let EntityType::Dimension(Dimension::Linear(live)) = doc.get_entity(handle).unwrap() else {
|
let Some(Dimension::Linear(live)) =
|
||||||
|
crate::entities::dimension::as_dimension(doc.get_entity(handle).unwrap())
|
||||||
|
else {
|
||||||
panic!("dimension missing from live document");
|
panic!("dimension missing from live document");
|
||||||
};
|
};
|
||||||
assert!(live.base.block_name.is_empty());
|
assert!(live.base.block_name.is_empty());
|
||||||
@@ -3582,7 +3208,7 @@ mod prepare_save_tests {
|
|||||||
let mut dim =
|
let mut dim =
|
||||||
DimensionLinear::new(Vector3::new(0.0, 0.0, 0.0), Vector3::new(10.0, 0.0, 0.0));
|
DimensionLinear::new(Vector3::new(0.0, 0.0, 0.0), Vector3::new(10.0, 0.0, 0.0));
|
||||||
dim.base.common.handle = doc.allocate_handle();
|
dim.base.common.handle = doc.allocate_handle();
|
||||||
doc.add_entity(EntityType::Dimension(Dimension::Linear(dim)))
|
doc.add_entity(EntityType::Dimension(Box::new(Dimension::Linear(dim))))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
for ext in ["dwg", "dxf"] {
|
for ext in ["dwg", "dxf"] {
|
||||||
let inline = save_to_bytes(&doc, ext, codec::DxfVersion::AC1032).expect("inline");
|
let inline = save_to_bytes(&doc, ext, codec::DxfVersion::AC1032).expect("inline");
|
||||||
|
|||||||
+1
-1
@@ -168,7 +168,7 @@ pub fn add_embedded_image(
|
|||||||
) -> Result<codec::Handle, String> {
|
) -> Result<codec::Handle, String> {
|
||||||
let (upper_left, lower_right) = corners_from_placement(origin, width, image.aspect());
|
let (upper_left, lower_right) = corners_from_placement(origin, width, image.aspect());
|
||||||
let ole = build_embedded_ole(image, upper_left, lower_right);
|
let ole = build_embedded_ole(image, upper_left, lower_right);
|
||||||
doc.add_entity(codec::EntityType::Ole2Frame(ole))
|
doc.add_entity(codec::EntityType::Ole2Frame(Box::new(ole)))
|
||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,8 +24,6 @@ pub struct RecoveryReport {
|
|||||||
pub source_sha256: Option<String>,
|
pub source_sha256: Option<String>,
|
||||||
pub read_stats: Option<codec::ReadStats>,
|
pub read_stats: Option<codec::ReadStats>,
|
||||||
pub entities_scanned: usize,
|
pub entities_scanned: usize,
|
||||||
pub entities_removed: usize,
|
|
||||||
pub referenced_entities_removed: usize,
|
|
||||||
pub parser_errors_recovered: usize,
|
pub parser_errors_recovered: usize,
|
||||||
pub diagnostics: Vec<(String, String)>,
|
pub diagnostics: Vec<(String, String)>,
|
||||||
pub references_checked: usize,
|
pub references_checked: usize,
|
||||||
@@ -54,8 +52,6 @@ impl RecoveryReport {
|
|||||||
source_sha256: Option<String>,
|
source_sha256: Option<String>,
|
||||||
read_stats: Option<codec::ReadStats>,
|
read_stats: Option<codec::ReadStats>,
|
||||||
entities_scanned: usize,
|
entities_scanned: usize,
|
||||||
entities_removed: usize,
|
|
||||||
referenced_entities_removed: usize,
|
|
||||||
references: &[XrefInfo],
|
references: &[XrefInfo],
|
||||||
notifications: &codec::notification::NotificationCollection,
|
notifications: &codec::notification::NotificationCollection,
|
||||||
save_as_required: bool,
|
save_as_required: bool,
|
||||||
@@ -163,8 +159,6 @@ impl RecoveryReport {
|
|||||||
source_sha256,
|
source_sha256,
|
||||||
read_stats,
|
read_stats,
|
||||||
entities_scanned,
|
entities_scanned,
|
||||||
entities_removed,
|
|
||||||
referenced_entities_removed,
|
|
||||||
parser_errors_recovered,
|
parser_errors_recovered,
|
||||||
diagnostics,
|
diagnostics,
|
||||||
references_checked: references.len(),
|
references_checked: references.len(),
|
||||||
@@ -211,8 +205,6 @@ impl RecoveryReport {
|
|||||||
.unwrap_or(0),
|
.unwrap_or(0),
|
||||||
read_stats,
|
read_stats,
|
||||||
entities_scanned: 0,
|
entities_scanned: 0,
|
||||||
entities_removed: 0,
|
|
||||||
referenced_entities_removed: 0,
|
|
||||||
diagnostics: Vec::new(),
|
diagnostics: Vec::new(),
|
||||||
references_checked: 0,
|
references_checked: 0,
|
||||||
references_loaded: 0,
|
references_loaded: 0,
|
||||||
@@ -233,17 +225,11 @@ impl RecoveryReport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn removed_total(&self) -> usize {
|
|
||||||
self.entities_removed
|
|
||||||
.saturating_add(self.referenced_entities_removed)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn issues_found(&self) -> usize {
|
pub fn issues_found(&self) -> usize {
|
||||||
self.parser_errors_recovered
|
self.parser_errors_recovered
|
||||||
.saturating_add(self.references_recovered)
|
.saturating_add(self.references_recovered)
|
||||||
.saturating_add(self.references_failed)
|
.saturating_add(self.references_failed)
|
||||||
.saturating_add(self.references_missing)
|
.saturating_add(self.references_missing)
|
||||||
.saturating_add(self.removed_total())
|
|
||||||
.saturating_add(usize::from(self.error.is_some()))
|
.saturating_add(usize::from(self.error.is_some()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,11 +301,6 @@ impl RecoveryReport {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
lines.push(format!("Entities scanned: {}", self.entities_scanned));
|
lines.push(format!("Entities scanned: {}", self.entities_scanned));
|
||||||
lines.push(format!("Entities removed: {}", self.entities_removed));
|
|
||||||
lines.push(format!(
|
|
||||||
"Referenced entities removed: {}",
|
|
||||||
self.referenced_entities_removed
|
|
||||||
));
|
|
||||||
lines.push(format!(
|
lines.push(format!(
|
||||||
"Parser errors recovered: {}",
|
"Parser errors recovered: {}",
|
||||||
self.parser_errors_recovered
|
self.parser_errors_recovered
|
||||||
|
|||||||
+17
-45
@@ -277,12 +277,8 @@ fn read_outcome_from_bytes(
|
|||||||
/// `base_dir`, and populate each xref block with entities from the
|
/// `base_dir`, and populate each xref block with entities from the
|
||||||
/// referenced file.
|
/// referenced file.
|
||||||
///
|
///
|
||||||
/// Returns a list of [`XrefInfo`] describing each xref block found, plus the
|
/// Returns a list of [`XrefInfo`] describing each xref block found.
|
||||||
/// number of corrupt xref entities dropped during merge. Purging happens
|
pub fn resolve_xrefs(doc: &mut CadDocument, base_dir: &Path) -> Vec<XrefInfo> {
|
||||||
/// inline as each xref's entities are merged — xref content is parser output
|
|
||||||
/// just like the host doc, so it gets the same corrupt-entity guard. Folding
|
|
||||||
/// it in here avoids a second full-document `entities()` walk after resolve.
|
|
||||||
pub fn resolve_xrefs(doc: &mut CadDocument, base_dir: &Path) -> (Vec<XrefInfo>, usize) {
|
|
||||||
resolve_xrefs_with_filter(doc, base_dir, None, None)
|
resolve_xrefs_with_filter(doc, base_dir, None, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,7 +291,7 @@ pub fn resolve_xrefs_for_keys(
|
|||||||
doc: &mut CadDocument,
|
doc: &mut CadDocument,
|
||||||
base_dir: &Path,
|
base_dir: &Path,
|
||||||
keys: &HashSet<Handle>,
|
keys: &HashSet<Handle>,
|
||||||
) -> (Vec<XrefInfo>, usize) {
|
) -> Vec<XrefInfo> {
|
||||||
resolve_xrefs_with_filter(doc, base_dir, None, Some(keys))
|
resolve_xrefs_with_filter(doc, base_dir, None, Some(keys))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,7 +304,7 @@ pub fn resolve_xrefs_with_progress(
|
|||||||
doc: &mut CadDocument,
|
doc: &mut CadDocument,
|
||||||
base_dir: &Path,
|
base_dir: &Path,
|
||||||
progress: Option<std::sync::Arc<dyn Fn(usize, usize) + Send + Sync>>,
|
progress: Option<std::sync::Arc<dyn Fn(usize, usize) + Send + Sync>>,
|
||||||
) -> (Vec<XrefInfo>, usize) {
|
) -> Vec<XrefInfo> {
|
||||||
resolve_xrefs_with_filter(doc, base_dir, progress, None)
|
resolve_xrefs_with_filter(doc, base_dir, progress, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,7 +313,7 @@ fn resolve_xrefs_with_filter(
|
|||||||
base_dir: &Path,
|
base_dir: &Path,
|
||||||
progress: Option<std::sync::Arc<dyn Fn(usize, usize) + Send + Sync>>,
|
progress: Option<std::sync::Arc<dyn Fn(usize, usize) + Send + Sync>>,
|
||||||
only: Option<&HashSet<Handle>>,
|
only: Option<&HashSet<Handle>>,
|
||||||
) -> (Vec<XrefInfo>, usize) {
|
) -> Vec<XrefInfo> {
|
||||||
// Auto-resolve every xref — frustum + LOD culling keep GPU cost bounded.
|
// Auto-resolve every xref — frustum + LOD culling keep GPU cost bounded.
|
||||||
let xref_entries: Vec<(String, String, Handle)> = doc
|
let xref_entries: Vec<(String, String, Handle)> = doc
|
||||||
.block_records
|
.block_records
|
||||||
@@ -432,7 +428,6 @@ fn resolve_xrefs_with_filter(
|
|||||||
// Phase 2 — merge each parsed xref into the host document, in the original
|
// Phase 2 — merge each parsed xref into the host document, in the original
|
||||||
// block order (par_iter preserves it), so handle allocation is deterministic.
|
// block order (par_iter preserves it), so handle allocation is deterministic.
|
||||||
let mut result = Vec::with_capacity(parsed.len());
|
let mut result = Vec::with_capacity(parsed.len());
|
||||||
let mut dropped = 0usize;
|
|
||||||
#[allow(unused_mut, unused_variables)]
|
#[allow(unused_mut, unused_variables)]
|
||||||
for (
|
for (
|
||||||
merge_index,
|
merge_index,
|
||||||
@@ -468,19 +463,7 @@ fn resolve_xrefs_with_filter(
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|diagnostic| diagnostic.message.clone()),
|
.map(|diagnostic| diagnostic.message.clone()),
|
||||||
);
|
);
|
||||||
let invalid = super::purge_corrupt_entities(&mut outcome.document);
|
if recovered {
|
||||||
if invalid > 0 {
|
|
||||||
diagnostics.push(format!(
|
|
||||||
"normal read found {invalid} structurally invalid reference records"
|
|
||||||
));
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
|
||||||
if source_sha256.is_none() {
|
|
||||||
source_sha256 = resolved.as_ref().and_then(|path| {
|
|
||||||
super::stable_sha256_file(path, initial_fingerprint.as_ref())
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if recovered || invalid > 0 {
|
|
||||||
(XrefStatus::Failed, diagnostics, Some(outcome.stats))
|
(XrefStatus::Failed, diagnostics, Some(outcome.stats))
|
||||||
} else {
|
} else {
|
||||||
// Reload is replacement, never append. Keep the prior merge
|
// Reload is replacement, never append. Keep the prior merge
|
||||||
@@ -502,7 +485,7 @@ fn resolve_xrefs_with_filter(
|
|||||||
let _ = unload_reference(doc, br_handle.value());
|
let _ = unload_reference(doc, br_handle.value());
|
||||||
remove_pipe_symbols(doc, &block_name);
|
remove_pipe_symbols(doc, &block_name);
|
||||||
ensure_block_entities(doc, &block_name);
|
ensure_block_entities(doc, &block_name);
|
||||||
dropped += merge_xref_into_block(doc, &block_name, br_handle, outcome.document);
|
merge_xref_into_block(doc, &block_name, br_handle, outcome.document);
|
||||||
if visretain {
|
if visretain {
|
||||||
restore_dependent_layers(doc, &block_name, kept_layers);
|
restore_dependent_layers(doc, &block_name, kept_layers);
|
||||||
}
|
}
|
||||||
@@ -533,7 +516,7 @@ fn resolve_xrefs_with_filter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(result, dropped)
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Underlay files named by a relative (or moved) path: read them from where
|
/// Underlay files named by a relative (or moved) path: read them from where
|
||||||
@@ -1218,13 +1201,12 @@ fn copy_xref_sortents(
|
|||||||
/// — which doesn't know about the xref's layers — and silently falls
|
/// — which doesn't know about the xref's layers — and silently falls
|
||||||
/// back to WHITE / 1 px line weight. AutoCAD's BIND command uses the
|
/// back to WHITE / 1 px line weight. AutoCAD's BIND command uses the
|
||||||
/// same naming scheme.
|
/// same naming scheme.
|
||||||
/// Returns the number of corrupt entities skipped during the merge.
|
|
||||||
fn merge_xref_into_block(
|
fn merge_xref_into_block(
|
||||||
doc: &mut CadDocument,
|
doc: &mut CadDocument,
|
||||||
xref_block_name: &str,
|
xref_block_name: &str,
|
||||||
br_handle: Handle,
|
br_handle: Handle,
|
||||||
xref_doc: CadDocument,
|
xref_doc: CadDocument,
|
||||||
) -> usize {
|
) {
|
||||||
let prefix = xref_block_name;
|
let prefix = xref_block_name;
|
||||||
|
|
||||||
// Carry the xref's INSUNITS onto the host BlockRecord. Used at INSERT
|
// Carry the xref's INSUNITS onto the host BlockRecord. Used at INSERT
|
||||||
@@ -1264,7 +1246,7 @@ fn merge_xref_into_block(
|
|||||||
// ── Entities (shared helper) ────────────────────────────────────────
|
// ── Entities (shared helper) ────────────────────────────────────────
|
||||||
// The unremapped-handle count is ignored on the load path (BIND reports
|
// The unremapped-handle count is ignored on the load path (BIND reports
|
||||||
// it per bind).
|
// it per bind).
|
||||||
let (dropped, _, entity_handle_map) = merge_source_entities(doc, &xref_doc, br_handle, &maps);
|
let (_, entity_handle_map) = merge_source_entities(doc, &xref_doc, br_handle, &maps);
|
||||||
|
|
||||||
// ── Draw-order overrides (shared helper) ──────────────────────────────
|
// ── Draw-order overrides (shared helper) ──────────────────────────────
|
||||||
copy_xref_sortents(
|
copy_xref_sortents(
|
||||||
@@ -1274,7 +1256,6 @@ fn merge_xref_into_block(
|
|||||||
&maps.br_handles,
|
&maps.br_handles,
|
||||||
&entity_handle_map,
|
&entity_handle_map,
|
||||||
);
|
);
|
||||||
dropped
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Source entities in display order: each block record's `entity_handles`
|
/// Source entities in display order: each block record's `entity_handles`
|
||||||
@@ -1308,26 +1289,18 @@ fn ordered_source_entities(xref_doc: &CadDocument) -> Vec<(Handle, EntityType)>
|
|||||||
|
|
||||||
/// Merge one source doc's entities into `target`, routing model-space content
|
/// Merge one source doc's entities into `target`, routing model-space content
|
||||||
/// into `target_br` and nested-block content into its imported counterpart
|
/// into `target_br` and nested-block content into its imported counterpart
|
||||||
/// (`maps.br_handles`). Returns corrupt-drop count, unremapped-handle count,
|
/// (`maps.br_handles`). Returns the unremapped-handle count and the old→new
|
||||||
/// and the old→new entity handle map for the sortents copy.
|
/// entity handle map for the sortents copy.
|
||||||
fn merge_source_entities(
|
fn merge_source_entities(
|
||||||
target: &mut CadDocument,
|
target: &mut CadDocument,
|
||||||
source: &CadDocument,
|
source: &CadDocument,
|
||||||
target_br: Handle,
|
target_br: Handle,
|
||||||
maps: &XrefSymbolMaps,
|
maps: &XrefSymbolMaps,
|
||||||
) -> (usize, usize, HashMap<Handle, Handle>) {
|
) -> (usize, HashMap<Handle, Handle>) {
|
||||||
let source_ms_handle = source.header.model_space_block_handle;
|
let source_ms_handle = source.header.model_space_block_handle;
|
||||||
let mut entity_handle_map: HashMap<Handle, Handle> = HashMap::default();
|
let mut entity_handle_map: HashMap<Handle, Handle> = HashMap::default();
|
||||||
let mut dropped = 0usize;
|
|
||||||
let mut unremapped = 0usize;
|
let mut unremapped = 0usize;
|
||||||
for (old_h, mut entity) in ordered_source_entities(source) {
|
for (old_h, mut entity) in ordered_source_entities(source) {
|
||||||
// Drop parser-garbage entities (bad normals / vertex counts / inf
|
|
||||||
// coords) before they enter the host doc — they trigger huge
|
|
||||||
// allocations and unbounded recursion in the wire pipeline.
|
|
||||||
if super::is_entity_corrupt(&entity) {
|
|
||||||
dropped += 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Remap every symbol reference so the host's resolver hits the copies
|
// Remap every symbol reference so the host's resolver hits the copies
|
||||||
// just imported (load path ignores the unremapped count; BIND reports
|
// just imported (load path ignores the unremapped count; BIND reports
|
||||||
// it per bind).
|
// it per bind).
|
||||||
@@ -1351,7 +1324,7 @@ fn merge_source_entities(
|
|||||||
entity_handle_map.insert(old_h, new_h);
|
entity_handle_map.insert(old_h, new_h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(dropped, unremapped, entity_handle_map)
|
(unremapped, entity_handle_map)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_sentinel_linetype(name: &str) -> bool {
|
fn is_sentinel_linetype(name: &str) -> bool {
|
||||||
@@ -2170,8 +2143,7 @@ fn merge_bound_doc(
|
|||||||
taken,
|
taken,
|
||||||
};
|
};
|
||||||
let maps = import_xref_symbols(target, source, &mut naming);
|
let maps = import_xref_symbols(target, source, &mut naming);
|
||||||
let (_, unremapped, entity_handle_map) =
|
let (unremapped, entity_handle_map) = merge_source_entities(target, source, target_br, &maps);
|
||||||
merge_source_entities(target, source, target_br, &maps);
|
|
||||||
copy_xref_sortents(
|
copy_xref_sortents(
|
||||||
target,
|
target,
|
||||||
source,
|
source,
|
||||||
@@ -2970,7 +2942,7 @@ mod tests {
|
|||||||
// 3. Targeted reload: back to Loaded.
|
// 3. Targeted reload: back to Loaded.
|
||||||
let mut handles = HashSet::default();
|
let mut handles = HashSet::default();
|
||||||
handles.insert(doc.block_records.get("MID").unwrap().handle);
|
handles.insert(doc.block_records.get("MID").unwrap().handle);
|
||||||
let (infos, _) = resolve_xrefs_for_keys(&mut doc, &dir, &handles);
|
let infos = resolve_xrefs_for_keys(&mut doc, &dir, &handles);
|
||||||
assert!(infos.iter().any(|i| i.name == "MID"));
|
assert!(infos.iter().any(|i| i.name == "MID"));
|
||||||
let listed = collect_entries_with_prev(&doc, &dir, &empty, &no_prev);
|
let listed = collect_entries_with_prev(&doc, &dir, &empty, &no_prev);
|
||||||
assert!(listed
|
assert!(listed
|
||||||
@@ -3336,7 +3308,7 @@ mod tests {
|
|||||||
// Hatch (pattern names have no table — preserved verbatim).
|
// Hatch (pattern names have no table — preserved verbatim).
|
||||||
let mut hatch = codec::entities::Hatch::new();
|
let mut hatch = codec::entities::Hatch::new();
|
||||||
hatch.pattern.name = "ANSI31".to_string();
|
hatch.pattern.name = "ANSI31".to_string();
|
||||||
doc.add_entity(codec::EntityType::Hatch(hatch)).unwrap();
|
doc.add_entity(codec::EntityType::Hatch(Box::new(hatch))).unwrap();
|
||||||
// Dim-style reference via a tolerance entity.
|
// Dim-style reference via a tolerance entity.
|
||||||
doc.dim_styles
|
doc.dim_styles
|
||||||
.add(codec::tables::DimStyle::new("ARCH"))
|
.add(codec::tables::DimStyle::new("ARCH"))
|
||||||
|
|||||||
@@ -696,10 +696,10 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static
|
|||||||
"ATTSYNC block name to sync:" => Some(("insert", "attsync-block-name-to-sync")),
|
"ATTSYNC block name to sync:" => Some(("insert", "attsync-block-name-to-sync")),
|
||||||
"ATTSYNC: no block named \"{arg}\"." => Some(("insert", "attsync-no-block-named-arg")),
|
"ATTSYNC: no block named \"{arg}\"." => Some(("insert", "attsync-no-block-named-arg")),
|
||||||
"ATTSYNC: synchronised {synced} insert(s) of \"{block}\" against {} attribute definition(s)." => Some(("insert", "attsync-synchronised-synced-insert-s-of-block")),
|
"ATTSYNC: synchronised {synced} insert(s) of \"{block}\" against {} attribute definition(s)." => Some(("insert", "attsync-synchronised-synced-insert-s-of-block")),
|
||||||
|
"AUDIT Fix any errors detected? [Yes / No] <No>:" => Some(("styles", "audit-fix-any-errors-detected")),
|
||||||
"AUDIT: no issues found." => Some(("styles", "audit-no-issues-found")),
|
"AUDIT: no issues found." => Some(("styles", "audit-no-issues-found")),
|
||||||
"AUDIT: reference(s) to undefined block(s): {}" => Some(("styles", "audit-reference-s-to-undefined-block-s")),
|
"AUDIT: {} error(s), {} warning(s) found." => Some(("styles", "audit-error-s-warning-s-found")),
|
||||||
"AUDIT: reference(s) to undefined layer(s): {}" => Some(("styles", "audit-reference-s-to-undefined-layer-s")),
|
"AUDIT: {} repair(s) applied, {} issue(s) left unresolved." => Some(("styles", "audit-repair-s-applied-issue-s-left")),
|
||||||
"AUDIT: report only — no automatic repair performed." => Some(("styles", "audit-report-only-no-automatic-repair-performe")),
|
|
||||||
"AUDIT: scanned {total} object(s)." => Some(("styles", "audit-scanned-total-object-s")),
|
"AUDIT: scanned {total} object(s)." => Some(("styles", "audit-scanned-total-object-s")),
|
||||||
"About" => Some(("manage", "about")),
|
"About" => Some(("manage", "about")),
|
||||||
"Above" => Some(("common", "above")),
|
"Above" => Some(("common", "above")),
|
||||||
@@ -3806,8 +3806,6 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static
|
|||||||
"WIPEOUT Rectangular Specify first corner:" => Some(("draw", "wipeout-rectangular-specify-first-corner")),
|
"WIPEOUT Rectangular Specify first corner:" => Some(("draw", "wipeout-rectangular-specify-first-corner")),
|
||||||
"WIPEOUT Rectangular Specify opposite corner:" => Some(("draw", "wipeout-rectangular-specify-opposite-corner")),
|
"WIPEOUT Rectangular Specify opposite corner:" => Some(("draw", "wipeout-rectangular-specify-opposite-corner")),
|
||||||
"Warning" => Some(("errors", "warning")),
|
"Warning" => Some(("errors", "warning")),
|
||||||
"Warning: {} corrupt entities dropped (parser junk — bad normals / counts)" => Some(("file", "warning-corrupt-entities-dropped-parser-junk-b")),
|
|
||||||
"Warning: {} corrupt xref entities dropped" => Some(("file", "warning-corrupt-xref-entities-dropped")),
|
|
||||||
"Watertight" => Some(("properties", "watertight")),
|
"Watertight" => Some(("properties", "watertight")),
|
||||||
"Web" => Some(("common", "web")),
|
"Web" => Some(("common", "web")),
|
||||||
"Web File" => Some(("properties", "web-file")),
|
"Web File" => Some(("properties", "web-file")),
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ pub(crate) fn aligned_dimension_entity(
|
|||||||
crate::entities::dimension::reset_automatic_text_position(&mut dim.base);
|
crate::entities::dimension::reset_automatic_text_position(&mut dim.base);
|
||||||
dim.base.actual_measurement = dim.measurement();
|
dim.base.actual_measurement = dim.measurement();
|
||||||
crate::entities::dimension::set_dimension_text_override(&mut dim.base, text_override);
|
crate::entities::dimension::set_dimension_text_override(&mut dim.base, text_override);
|
||||||
EntityType::Dimension(Dimension::Aligned(dim))
|
EntityType::Dimension(Box::new(Dimension::Aligned(dim)))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CadCommand for AlignedDimensionCommand {
|
impl CadCommand for AlignedDimensionCommand {
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ impl AngularDimensionCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn commit(&self, dimension: Dimension) -> CmdResult {
|
fn commit(&self, dimension: Dimension) -> CmdResult {
|
||||||
let entity = self.plane.place_entity(EntityType::Dimension(dimension));
|
let entity = self.plane.place_entity(EntityType::Dimension(Box::new(dimension)));
|
||||||
CmdResult::CommitDimension {
|
CmdResult::CommitDimension {
|
||||||
entity,
|
entity,
|
||||||
association: DimensionAssociationInput::Explicit(self.source_refs.clone()),
|
association: DimensionAssociationInput::Explicit(self.source_refs.clone()),
|
||||||
@@ -1242,7 +1242,7 @@ pub(crate) fn angular_two_line_entity(
|
|||||||
dim.base.insertion_point = dim.dimension_arc;
|
dim.base.insertion_point = dim.dimension_arc;
|
||||||
dim.base.actual_measurement = dim.measurement_degrees();
|
dim.base.actual_measurement = dim.measurement_degrees();
|
||||||
crate::entities::dimension::set_dimension_text_override(&mut dim.base, text);
|
crate::entities::dimension::set_dimension_text_override(&mut dim.base, text);
|
||||||
Some(EntityType::Dimension(Dimension::Angular2Ln(dim)))
|
Some(EntityType::Dimension(Box::new(Dimension::Angular2Ln(dim))))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A three-point angular dimension (vertex, two points, arc point), for a
|
/// A three-point angular dimension (vertex, two points, arc point), for a
|
||||||
@@ -1261,7 +1261,7 @@ pub(crate) fn angular_three_point_entity(
|
|||||||
dim.base.insertion_point = dim.definition_point;
|
dim.base.insertion_point = dim.definition_point;
|
||||||
dim.base.actual_measurement = dim.measurement_degrees();
|
dim.base.actual_measurement = dim.measurement_degrees();
|
||||||
crate::entities::dimension::set_dimension_text_override(&mut dim.base, text);
|
crate::entities::dimension::set_dimension_text_override(&mut dim.base, text);
|
||||||
Some(EntityType::Dimension(Dimension::Angular3Pt(dim)))
|
Some(EntityType::Dimension(Box::new(Dimension::Angular3Pt(dim))))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn v3(point: DVec3) -> Vector3 {
|
fn v3(point: DVec3) -> Vector3 {
|
||||||
|
|||||||
@@ -258,7 +258,7 @@ impl ArcLengthDimensionCommand {
|
|||||||
|handle| DimensionAssociationInput::Explicit(selection.association_sources(handle)),
|
|handle| DimensionAssociationInput::Explicit(selection.association_sources(handle)),
|
||||||
);
|
);
|
||||||
CmdResult::CommitDimension {
|
CmdResult::CommitDimension {
|
||||||
entity: plane.place_entity(EntityType::Dimension(Dimension::Arc(dimension))),
|
entity: plane.place_entity(EntityType::Dimension(Box::new(Dimension::Arc(dimension)))),
|
||||||
association,
|
association,
|
||||||
preserve_base_style: false,
|
preserve_base_style: false,
|
||||||
continue_command: false,
|
continue_command: false,
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ impl DiameterDimensionCommand {
|
|||||||
if let Some(angle) = self.text_angle {
|
if let Some(angle) = self.text_angle {
|
||||||
dim.base.text_rotation = angle;
|
dim.base.text_rotation = angle;
|
||||||
}
|
}
|
||||||
plane.place_entity(EntityType::Dimension(Dimension::Diameter(dim)))
|
plane.place_entity(EntityType::Dimension(Box::new(Dimension::Diameter(dim))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ pub(crate) fn diameter_constraint_entity(
|
|||||||
dim.leader_length = chord.distance(location).max(radius * 0.5);
|
dim.leader_length = chord.distance(location).max(radius * 0.5);
|
||||||
dim.base.actual_measurement = dim.measurement();
|
dim.base.actual_measurement = dim.measurement();
|
||||||
crate::entities::dimension::set_dimension_text_override(&mut dim.base, text);
|
crate::entities::dimension::set_dimension_text_override(&mut dim.base, text);
|
||||||
Some(EntityType::Dimension(Dimension::Diameter(dim)))
|
Some(EntityType::Dimension(Box::new(Dimension::Diameter(dim))))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CadCommand for DiameterDimensionCommand {
|
impl CadCommand for DiameterDimensionCommand {
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ impl DimBaselineCommand {
|
|||||||
let increment = self.effective_increment(&style.style_name);
|
let increment = self.effective_increment(&style.style_name);
|
||||||
let plane = plane_from_normal(dimension.base().definition_point, style.normal);
|
let plane = plane_from_normal(dimension.base().definition_point, style.normal);
|
||||||
let pick = pick.and_then(|point| plane.project(point.to_array()).map(Vec2::from));
|
let pick = pick.and_then(|point| plane.project(point.to_array()).map(Vec2::from));
|
||||||
let kind = match dimension {
|
let kind = match &**dimension {
|
||||||
Dimension::Linear(source) => {
|
Dimension::Linear(source) => {
|
||||||
let first = project(&plane, source.first_point);
|
let first = project(&plane, source.first_point);
|
||||||
let second = project(&plane, source.second_point);
|
let second = project(&plane, source.second_point);
|
||||||
@@ -441,7 +441,7 @@ impl CadCommand for DimBaselineCommand {
|
|||||||
self.committed += 1;
|
self.committed += 1;
|
||||||
self.advance(1.0);
|
self.advance(1.0);
|
||||||
CmdResult::CommitDimension {
|
CmdResult::CommitDimension {
|
||||||
entity: EntityType::Dimension(dimension),
|
entity: EntityType::Dimension(Box::new(dimension)),
|
||||||
association: DimensionAssociationInput::Infer(None),
|
association: DimensionAssociationInput::Infer(None),
|
||||||
preserve_base_style: self.preserve_base_style,
|
preserve_base_style: self.preserve_base_style,
|
||||||
continue_command: true,
|
continue_command: true,
|
||||||
@@ -489,7 +489,7 @@ impl CadCommand for DimBaselineCommand {
|
|||||||
fn dimension_preview(&self, cursor: DVec3) -> Option<Vec<DimensionPreview>> {
|
fn dimension_preview(&self, cursor: DVec3) -> Option<Vec<DimensionPreview>> {
|
||||||
self.build_dimension(cursor).map(|dimension| {
|
self.build_dimension(cursor).map(|dimension| {
|
||||||
vec![DimensionPreview {
|
vec![DimensionPreview {
|
||||||
entity: EntityType::Dimension(dimension),
|
entity: EntityType::Dimension(Box::new(dimension)),
|
||||||
preserve_base_style: self.preserve_base_style,
|
preserve_base_style: self.preserve_base_style,
|
||||||
}]
|
}]
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ impl DimContinueCommand {
|
|||||||
let style = SourceStyle::from_base(dimension.base());
|
let style = SourceStyle::from_base(dimension.base());
|
||||||
let plane = plane_from_normal(dimension.base().definition_point, style.normal);
|
let plane = plane_from_normal(dimension.base().definition_point, style.normal);
|
||||||
let pick = pick_world.and_then(|point| plane.project(point.to_array()).map(Vec2::from));
|
let pick = pick_world.and_then(|point| plane.project(point.to_array()).map(Vec2::from));
|
||||||
let kind = match dimension {
|
let kind = match &**dimension {
|
||||||
Dimension::Linear(source) => {
|
Dimension::Linear(source) => {
|
||||||
let rotation = source.rotation;
|
let rotation = source.rotation;
|
||||||
let perpendicular = Vec2::new(-rotation.sin(), rotation.cos());
|
let perpendicular = Vec2::new(-rotation.sin(), rotation.cos());
|
||||||
@@ -383,7 +383,7 @@ impl CadCommand for DimContinueCommand {
|
|||||||
}
|
}
|
||||||
self.advance(point);
|
self.advance(point);
|
||||||
CmdResult::CommitDimension {
|
CmdResult::CommitDimension {
|
||||||
entity: EntityType::Dimension(dimension),
|
entity: EntityType::Dimension(Box::new(dimension)),
|
||||||
association: DimensionAssociationInput::Infer(None),
|
association: DimensionAssociationInput::Infer(None),
|
||||||
preserve_base_style: self.preserve_base_style,
|
preserve_base_style: self.preserve_base_style,
|
||||||
continue_command: true,
|
continue_command: true,
|
||||||
@@ -433,7 +433,7 @@ impl CadCommand for DimContinueCommand {
|
|||||||
fn dimension_preview(&self, cursor: DVec3) -> Option<Vec<DimensionPreview>> {
|
fn dimension_preview(&self, cursor: DVec3) -> Option<Vec<DimensionPreview>> {
|
||||||
self.build_dimension(cursor).map(|dimension| {
|
self.build_dimension(cursor).map(|dimension| {
|
||||||
vec![DimensionPreview {
|
vec![DimensionPreview {
|
||||||
entity: EntityType::Dimension(dimension),
|
entity: EntityType::Dimension(Box::new(dimension)),
|
||||||
preserve_base_style: self.preserve_base_style,
|
preserve_base_style: self.preserve_base_style,
|
||||||
}]
|
}]
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -145,13 +145,17 @@ impl CadCommand for DimJogLineCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn on_entity_pick(&mut self, handle: Handle, _point: DVec3) -> CmdResult {
|
fn on_entity_pick(&mut self, handle: Handle, _point: DVec3) -> CmdResult {
|
||||||
let Some(EntityType::Dimension(dimension @ (Dimension::Linear(_) | Dimension::Aligned(_)))) =
|
let Some(EntityType::Dimension(dimension)) = self.picked_entity.take() else {
|
||||||
self.picked_entity.take()
|
|
||||||
else {
|
|
||||||
return CmdResult::ReportError(
|
return CmdResult::ReportError(
|
||||||
t!("DIMJOGLINE: select a linear or aligned dimension.").into_owned(),
|
t!("DIMJOGLINE: select a linear or aligned dimension.").into_owned(),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
let dimension = *dimension;
|
||||||
|
if !matches!(dimension, Dimension::Linear(_) | Dimension::Aligned(_)) {
|
||||||
|
return CmdResult::ReportError(
|
||||||
|
t!("DIMJOGLINE: select a linear or aligned dimension.").into_owned(),
|
||||||
|
);
|
||||||
|
}
|
||||||
if handle.is_null() {
|
if handle.is_null() {
|
||||||
return CmdResult::NeedPoint;
|
return CmdResult::NeedPoint;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,8 +104,8 @@ impl CadCommand for DimSpaceCommand {
|
|||||||
for selected in entities {
|
for selected in entities {
|
||||||
if selected.handle != *base
|
if selected.handle != *base
|
||||||
&& matches!(
|
&& matches!(
|
||||||
selected.entity,
|
crate::entities::dimension::as_dimension(&selected.entity),
|
||||||
EntityType::Dimension(
|
Some(
|
||||||
codec::entities::Dimension::Linear(_)
|
codec::entities::Dimension::Linear(_)
|
||||||
| codec::entities::Dimension::Aligned(_)
|
| codec::entities::Dimension::Aligned(_)
|
||||||
)
|
)
|
||||||
@@ -124,11 +124,14 @@ impl CadCommand for DimSpaceCommand {
|
|||||||
match &mut self.step {
|
match &mut self.step {
|
||||||
Step::PickBase => {
|
Step::PickBase => {
|
||||||
if !matches!(
|
if !matches!(
|
||||||
self.picked_entity.take(),
|
self.picked_entity
|
||||||
Some(EntityType::Dimension(
|
.take()
|
||||||
|
.as_ref()
|
||||||
|
.and_then(crate::entities::dimension::as_dimension),
|
||||||
|
Some(
|
||||||
codec::entities::Dimension::Linear(_)
|
codec::entities::Dimension::Linear(_)
|
||||||
| codec::entities::Dimension::Aligned(_)
|
| codec::entities::Dimension::Aligned(_)
|
||||||
))
|
)
|
||||||
) {
|
) {
|
||||||
return CmdResult::ReportError(
|
return CmdResult::ReportError(
|
||||||
t!("DIMSPACE: select a linear or aligned dimension.").into_owned(),
|
t!("DIMSPACE: select a linear or aligned dimension.").into_owned(),
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ impl CadCommand for FieldPlaceCommand {
|
|||||||
mtext.attachment_point = self.attachment;
|
mtext.attachment_point = self.attachment;
|
||||||
// No defined width: the field text never wraps.
|
// No defined width: the field text never wraps.
|
||||||
mtext.rectangle_width = 0.0;
|
mtext.rectangle_width = 0.0;
|
||||||
CmdResult::CommitAndExit(self.plane.place_entity(EntityType::MText(mtext)))
|
CmdResult::CommitAndExit(self.plane.place_entity(EntityType::MText(Box::new(mtext))))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_enter(&mut self) -> CmdResult {
|
fn on_enter(&mut self) -> CmdResult {
|
||||||
|
|||||||
@@ -138,7 +138,9 @@ impl JoggedRadiusDimensionCommand {
|
|||||||
);
|
);
|
||||||
|
|
||||||
CmdResult::CommitDimension {
|
CmdResult::CommitDimension {
|
||||||
entity: plane.place_entity(EntityType::Dimension(Dimension::LargeRadial(dimension))),
|
entity: plane.place_entity(EntityType::Dimension(Box::new(Dimension::LargeRadial(
|
||||||
|
dimension,
|
||||||
|
)))),
|
||||||
association,
|
association,
|
||||||
preserve_base_style: false,
|
preserve_base_style: false,
|
||||||
continue_command: false,
|
continue_command: false,
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ impl LeaderCommand {
|
|||||||
CmdResult::CommitManyAndEditText {
|
CmdResult::CommitManyAndEditText {
|
||||||
entities: vec![
|
entities: vec![
|
||||||
self.plane.place_entity(EntityType::Leader(leader)),
|
self.plane.place_entity(EntityType::Leader(leader)),
|
||||||
self.plane.place_entity(EntityType::MText(mtext)),
|
self.plane.place_entity(EntityType::MText(Box::new(mtext))),
|
||||||
],
|
],
|
||||||
edit_index: 1,
|
edit_index: 1,
|
||||||
open_editor,
|
open_editor,
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ pub(crate) fn linear_dimension_entity(
|
|||||||
crate::entities::dimension::reset_automatic_text_position(&mut dim.base);
|
crate::entities::dimension::reset_automatic_text_position(&mut dim.base);
|
||||||
dim.base.actual_measurement = dim.measurement();
|
dim.base.actual_measurement = dim.measurement();
|
||||||
crate::entities::dimension::set_dimension_text_override(&mut dim.base, text_override);
|
crate::entities::dimension::set_dimension_text_override(&mut dim.base, text_override);
|
||||||
EntityType::Dimension(Dimension::Linear(dim))
|
EntityType::Dimension(Box::new(Dimension::Linear(dim)))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CadCommand for LinearDimensionCommand {
|
impl CadCommand for LinearDimensionCommand {
|
||||||
|
|||||||
@@ -648,7 +648,7 @@ impl CadCommand for MLeaderCommand {
|
|||||||
text.insertion_point.z,
|
text.insertion_point.z,
|
||||||
));
|
));
|
||||||
self.text = text.value.clone();
|
self.text = text.value.clone();
|
||||||
self.selected_mtext = Some(text);
|
self.selected_mtext = Some(*text);
|
||||||
self.content_type = LeaderContentType::MText;
|
self.content_type = LeaderContentType::MText;
|
||||||
self.order = CreationOrder::ContentFirst;
|
self.order = CreationOrder::ContentFirst;
|
||||||
self.step = Step::PickPoints;
|
self.step = Step::PickPoints;
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ impl OrdinateDimCommand {
|
|||||||
}
|
}
|
||||||
dim.refresh_measurement();
|
dim.refresh_measurement();
|
||||||
self.plane
|
self.plane
|
||||||
.place_entity(EntityType::Dimension(Dimension::Ordinate(dim)))
|
.place_entity(EntityType::Dimension(Box::new(Dimension::Ordinate(dim))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -341,7 +341,7 @@ impl QdimCommand {
|
|||||||
]);
|
]);
|
||||||
(
|
(
|
||||||
self.plane
|
self.plane
|
||||||
.place_entity(EntityType::Dimension(Dimension::Linear(dimension))),
|
.place_entity(EntityType::Dimension(Box::new(Dimension::Linear(dimension)))),
|
||||||
association,
|
association,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -366,7 +366,7 @@ impl QdimCommand {
|
|||||||
dimension.refresh_measurement();
|
dimension.refresh_measurement();
|
||||||
(
|
(
|
||||||
self.plane
|
self.plane
|
||||||
.place_entity(EntityType::Dimension(Dimension::Ordinate(dimension))),
|
.place_entity(EntityType::Dimension(Box::new(Dimension::Ordinate(dimension)))),
|
||||||
DimensionAssociationInput::Explicit(vec![point.sources.first().copied()]),
|
DimensionAssociationInput::Explicit(vec![point.sources.first().copied()]),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -405,7 +405,7 @@ impl QdimCommand {
|
|||||||
dimension.base.text_user_positioned = true;
|
dimension.base.text_user_positioned = true;
|
||||||
dimension.leader_length = chord.distance(text);
|
dimension.leader_length = chord.distance(text);
|
||||||
dimension.base.actual_measurement = dimension.measurement();
|
dimension.base.actual_measurement = dimension.measurement();
|
||||||
EntityType::Dimension(Dimension::Radius(dimension))
|
EntityType::Dimension(Box::new(Dimension::Radius(dimension)))
|
||||||
} else {
|
} else {
|
||||||
let opposite = center - direction * radius;
|
let opposite = center - direction * radius;
|
||||||
let mut dimension = DimensionDiameter::new(v3(chord), v3(opposite));
|
let mut dimension = DimensionDiameter::new(v3(chord), v3(opposite));
|
||||||
@@ -415,7 +415,7 @@ impl QdimCommand {
|
|||||||
dimension.base.text_user_positioned = true;
|
dimension.base.text_user_positioned = true;
|
||||||
dimension.leader_length = chord.distance(text);
|
dimension.leader_length = chord.distance(text);
|
||||||
dimension.base.actual_measurement = dimension.measurement();
|
dimension.base.actual_measurement = dimension.measurement();
|
||||||
EntityType::Dimension(Dimension::Diameter(dimension))
|
EntityType::Dimension(Box::new(Dimension::Diameter(dimension)))
|
||||||
};
|
};
|
||||||
(self.plane.place_entity(entity), association)
|
(self.plane.place_entity(entity), association)
|
||||||
})
|
})
|
||||||
@@ -680,7 +680,7 @@ fn preview_entity(index: usize, entity: &EntityType) -> Vec<WireModel> {
|
|||||||
return Vec::new();
|
return Vec::new();
|
||||||
};
|
};
|
||||||
let mut lines: Vec<Vec<[f64; 3]>> = Vec::new();
|
let mut lines: Vec<Vec<[f64; 3]>> = Vec::new();
|
||||||
match dimension {
|
match &**dimension {
|
||||||
Dimension::Linear(value) => {
|
Dimension::Linear(value) => {
|
||||||
let first = d3(value.first_point);
|
let first = d3(value.first_point);
|
||||||
let second = d3(value.second_point);
|
let second = d3(value.second_point);
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ pub(crate) fn radial_dimension_entity(
|
|||||||
if let Some(angle) = text_angle {
|
if let Some(angle) = text_angle {
|
||||||
dim.base.text_rotation = angle;
|
dim.base.text_rotation = angle;
|
||||||
}
|
}
|
||||||
plane.place_entity(EntityType::Dimension(Dimension::Radius(dim)))
|
plane.place_entity(EntityType::Dimension(Box::new(Dimension::Radius(dim))))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A radius dimension for a dimensional constraint: the leader leaves the
|
/// A radius dimension for a dimensional constraint: the leader leaves the
|
||||||
@@ -111,7 +111,7 @@ pub(crate) fn radius_constraint_entity(
|
|||||||
dim.leader_length = chord.distance(location).max(radius * 0.5);
|
dim.leader_length = chord.distance(location).max(radius * 0.5);
|
||||||
dim.base.actual_measurement = dim.measurement();
|
dim.base.actual_measurement = dim.measurement();
|
||||||
crate::entities::dimension::set_dimension_text_override(&mut dim.base, text);
|
crate::entities::dimension::set_dimension_text_override(&mut dim.base, text);
|
||||||
Some(EntityType::Dimension(Dimension::Radius(dim)))
|
Some(EntityType::Dimension(Box::new(Dimension::Radius(dim))))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The unit direction a radial constraint's dimension points in, from the
|
/// The unit direction a radial constraint's dimension points in, from the
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ fn separate(p: &Piece, doc: &CadDocument) -> Vec<EntityType> {
|
|||||||
let at = p.point(p.rect[0] + x * (p.rect[1] - p.rect[0]), p.rect[3]);
|
let at = p.point(p.rect[0] + x * (p.rect[1] - p.rect[0]), p.rect[3]);
|
||||||
let mut m = mtext_from(p.entity, p.content.clone(), at, p.height, p.rotation);
|
let mut m = mtext_from(p.entity, p.content.clone(), at, p.height, p.rotation);
|
||||||
m.attachment_point = attachment;
|
m.attachment_point = attachment;
|
||||||
vec![EntityType::MText(m)]
|
vec![EntityType::MText(Box::new(m))]
|
||||||
}
|
}
|
||||||
EntityType::MText(m) => {
|
EntityType::MText(m) => {
|
||||||
// The drawn words, grouped into lines by their baseline.
|
// The drawn words, grouped into lines by their baseline.
|
||||||
@@ -261,7 +261,8 @@ fn separate(p: &Piece, doc: &CadDocument) -> Vec<EntityType> {
|
|||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(" ");
|
.join(" ");
|
||||||
let at = p.point(line[0].0 - origin_along, p.rect[3] - k as f64 * step);
|
let at = p.point(line[0].0 - origin_along, p.rect[3] - k as f64 * step);
|
||||||
EntityType::MText(mtext_from(p.entity, value, at, line[0].1.height, m.rotation))
|
let height = line[0].1.height;
|
||||||
|
EntityType::MText(Box::new(mtext_from(p.entity, value, at, height, m.rotation)))
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
@@ -352,7 +353,7 @@ pub fn plan(
|
|||||||
}
|
}
|
||||||
Some(Txt2MtxtPlan {
|
Some(Txt2MtxtPlan {
|
||||||
erase: pieces.iter().map(|p| p.handle).collect(),
|
erase: pieces.iter().map(|p| p.handle).collect(),
|
||||||
add: vec![EntityType::MText(m)],
|
add: vec![EntityType::MText(Box::new(m))],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ impl CadCommand for PasteSpecCommand {
|
|||||||
mtext.style = self.style.clone();
|
mtext.style = self.style.clone();
|
||||||
mtext.attachment_point = AttachmentPoint::TopLeft;
|
mtext.attachment_point = AttachmentPoint::TopLeft;
|
||||||
mtext.rectangle_width = 0.0;
|
mtext.rectangle_width = 0.0;
|
||||||
CmdResult::CommitAndExit(self.plane.place_entity(EntityType::MText(mtext)))
|
CmdResult::CommitAndExit(self.plane.place_entity(EntityType::MText(Box::new(mtext))))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_enter(&mut self) -> CmdResult {
|
fn on_enter(&mut self) -> CmdResult {
|
||||||
|
|||||||
@@ -925,7 +925,7 @@ mod tests {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
hatch.paths.push(path);
|
hatch.paths.push(path);
|
||||||
let entity = EntityType::Hatch(hatch);
|
let entity = EntityType::Hatch(Box::new(hatch));
|
||||||
HatcheditCommand::with_handle(Handle::new(7), "ANSI31".into(), 1.0, 0.0, false)
|
HatcheditCommand::with_handle(Handle::new(7), "ANSI31".into(), 1.0, 0.0, false)
|
||||||
.with_appearance(Some(&entity), Color::Index(6), Transparency::T_40)
|
.with_appearance(Some(&entity), Color::Index(6), Transparency::T_40)
|
||||||
.with_origin([9.0, 8.0])
|
.with_origin([9.0, 8.0])
|
||||||
@@ -1096,7 +1096,7 @@ mod tests {
|
|||||||
counter_clockwise: true,
|
counter_clockwise: true,
|
||||||
}));
|
}));
|
||||||
hatch.paths.push(path);
|
hatch.paths.push(path);
|
||||||
let entity = EntityType::Hatch(hatch);
|
let entity = EntityType::Hatch(Box::new(hatch));
|
||||||
let mut command =
|
let mut command =
|
||||||
HatcheditCommand::with_handle(Handle::new(7), "ANSI31".into(), 1.0, 0.0, false)
|
HatcheditCommand::with_handle(Handle::new(7), "ANSI31".into(), 1.0, 0.0, false)
|
||||||
.with_appearance(Some(&entity), Color::ByLayer, Transparency::ByLayer);
|
.with_appearance(Some(&entity), Color::ByLayer, Transparency::ByLayer);
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ impl ImageCommand {
|
|||||||
let (upper_left, lower_right) =
|
let (upper_left, lower_right) =
|
||||||
corners_from_placement(ins, world_width, self.aspect());
|
corners_from_placement(ins, world_width, self.aspect());
|
||||||
let ole = build_embedded_ole(image, upper_left, lower_right);
|
let ole = build_embedded_ole(image, upper_left, lower_right);
|
||||||
self.plane.place_entity(EntityType::Ole2Frame(ole))
|
self.plane.place_entity(EntityType::Ole2Frame(Box::new(ole)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1439,7 +1439,7 @@ fn sync_dimension_base_points_and_collect_pending(doc: &mut CadDocument) -> Vec<
|
|||||||
let EntityType::Dimension(dimension) = entity else {
|
let EntityType::Dimension(dimension) = entity else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let definition_point = match dimension {
|
let definition_point = match &**dimension {
|
||||||
Dimension::Linear(value) => Some(value.definition_point),
|
Dimension::Linear(value) => Some(value.definition_point),
|
||||||
Dimension::Aligned(value) => Some(value.definition_point),
|
Dimension::Aligned(value) => Some(value.definition_point),
|
||||||
Dimension::Radius(value) => Some(value.definition_point),
|
Dimension::Radius(value) => Some(value.definition_point),
|
||||||
@@ -1493,7 +1493,7 @@ pub fn bake_dimension_blocks(doc: &mut CadDocument) {
|
|||||||
let dimensions: Vec<(Handle, Dimension)> = pending
|
let dimensions: Vec<(Handle, Dimension)> = pending
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|handle| match doc.get_entity(handle) {
|
.filter_map(|handle| match doc.get_entity(handle) {
|
||||||
Some(EntityType::Dimension(d)) => Some((handle, d.clone())),
|
Some(EntityType::Dimension(d)) => Some((handle, (**d).clone())),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
@@ -1654,7 +1654,7 @@ mod tests {
|
|||||||
d.base.text_middle_point = Vector3::new(5.0, 5.0, 0.0);
|
d.base.text_middle_point = Vector3::new(5.0, 5.0, 0.0);
|
||||||
// block_name is left empty — exactly what OCS-created dimensions carry.
|
// block_name is left empty — exactly what OCS-created dimensions carry.
|
||||||
let handle = doc
|
let handle = doc
|
||||||
.add_entity(EntityType::Dimension(Dimension::Linear(d)))
|
.add_entity(EntityType::Dimension(Box::new(Dimension::Linear(d))))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
bake_dimension_blocks(&mut doc);
|
bake_dimension_blocks(&mut doc);
|
||||||
@@ -1693,7 +1693,7 @@ mod tests {
|
|||||||
// Exactly what OCS-created dimensions carry: insertion == text anchor.
|
// Exactly what OCS-created dimensions carry: insertion == text anchor.
|
||||||
d.base.insertion_point = d.base.text_middle_point;
|
d.base.insertion_point = d.base.text_middle_point;
|
||||||
let handle = doc
|
let handle = doc
|
||||||
.add_entity(EntityType::Dimension(Dimension::Linear(d)))
|
.add_entity(EntityType::Dimension(Box::new(Dimension::Linear(d))))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
bake_dimension_blocks(&mut doc);
|
bake_dimension_blocks(&mut doc);
|
||||||
@@ -1720,7 +1720,7 @@ mod tests {
|
|||||||
d.definition_point = Vector3::new(0.0, 5.0, 0.0);
|
d.definition_point = Vector3::new(0.0, 5.0, 0.0);
|
||||||
d.base.text_middle_point = Vector3::new(5.0, 5.0, 0.0);
|
d.base.text_middle_point = Vector3::new(5.0, 5.0, 0.0);
|
||||||
let handle = doc
|
let handle = doc
|
||||||
.add_entity(EntityType::Dimension(Dimension::Linear(d)))
|
.add_entity(EntityType::Dimension(Box::new(Dimension::Linear(d))))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
bake_dimension_blocks(&mut doc);
|
bake_dimension_blocks(&mut doc);
|
||||||
@@ -1798,7 +1798,7 @@ mod tests {
|
|||||||
d.rotation = 0.0;
|
d.rotation = 0.0;
|
||||||
d.definition_point = Vector3::new(0.0, 8.0, 0.0);
|
d.definition_point = Vector3::new(0.0, 8.0, 0.0);
|
||||||
let handle = doc
|
let handle = doc
|
||||||
.add_entity(EntityType::Dimension(Dimension::Linear(d)))
|
.add_entity(EntityType::Dimension(Box::new(Dimension::Linear(d))))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
bake_dimension_blocks(&mut doc);
|
bake_dimension_blocks(&mut doc);
|
||||||
let name = match doc.get_entity(handle) {
|
let name = match doc.get_entity(handle) {
|
||||||
@@ -1827,7 +1827,7 @@ mod tests {
|
|||||||
let mut d = DimensionLinear::new(Vector3::new(0.0, 0.0, 0.0), Vector3::new(10.0, 0.0, 0.0));
|
let mut d = DimensionLinear::new(Vector3::new(0.0, 0.0, 0.0), Vector3::new(10.0, 0.0, 0.0));
|
||||||
d.definition_point = Vector3::new(0.0, 5.0, 0.0);
|
d.definition_point = Vector3::new(0.0, 5.0, 0.0);
|
||||||
let handle = doc
|
let handle = doc
|
||||||
.add_entity(EntityType::Dimension(Dimension::Linear(d)))
|
.add_entity(EntityType::Dimension(Box::new(Dimension::Linear(d))))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
bake_dimension_blocks(&mut doc);
|
bake_dimension_blocks(&mut doc);
|
||||||
let name = match doc.get_entity(handle) {
|
let name = match doc.get_entity(handle) {
|
||||||
@@ -1875,7 +1875,7 @@ mod tests {
|
|||||||
.collect();
|
.collect();
|
||||||
assert!(!expected.is_empty(), "the dimension explodes into no lines");
|
assert!(!expected.is_empty(), "the dimension explodes into no lines");
|
||||||
|
|
||||||
let mut turned = EntityType::Dimension(flat);
|
let mut turned = EntityType::Dimension(Box::new(flat));
|
||||||
crate::scene::view::dispatch::apply_transform(
|
crate::scene::view::dispatch::apply_transform(
|
||||||
&mut turned,
|
&mut turned,
|
||||||
&EntityTransform::Rotate {
|
&EntityTransform::Rotate {
|
||||||
@@ -1911,7 +1911,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
d.definition_point = Vector3::new(5.0, 5.0, 0.0); // arc location
|
d.definition_point = Vector3::new(5.0, 5.0, 0.0); // arc location
|
||||||
let handle = doc
|
let handle = doc
|
||||||
.add_entity(EntityType::Dimension(Dimension::Angular3Pt(d)))
|
.add_entity(EntityType::Dimension(Box::new(Dimension::Angular3Pt(d))))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
bake_dimension_blocks(&mut doc);
|
bake_dimension_blocks(&mut doc);
|
||||||
let name = match doc.get_entity(handle) {
|
let name = match doc.get_entity(handle) {
|
||||||
@@ -1940,7 +1940,7 @@ mod tests {
|
|||||||
let mut d = DimensionDiameter::new(edge, far);
|
let mut d = DimensionDiameter::new(edge, far);
|
||||||
d.base.text_middle_point = Vector3::new(3.0, 9.0, 0.0);
|
d.base.text_middle_point = Vector3::new(3.0, 9.0, 0.0);
|
||||||
let handle = doc
|
let handle = doc
|
||||||
.add_entity(EntityType::Dimension(Dimension::Diameter(d)))
|
.add_entity(EntityType::Dimension(Box::new(Dimension::Diameter(d))))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
bake_dimension_blocks(&mut doc);
|
bake_dimension_blocks(&mut doc);
|
||||||
let name = match doc.get_entity(handle) {
|
let name = match doc.get_entity(handle) {
|
||||||
@@ -1971,7 +1971,7 @@ mod tests {
|
|||||||
d.rotation = std::f64::consts::FRAC_PI_2; // 90°, vertical dimension line
|
d.rotation = std::f64::consts::FRAC_PI_2; // 90°, vertical dimension line
|
||||||
d.definition_point = Vector3::new(8.0, 0.0, 0.0);
|
d.definition_point = Vector3::new(8.0, 0.0, 0.0);
|
||||||
let handle = doc
|
let handle = doc
|
||||||
.add_entity(EntityType::Dimension(Dimension::Linear(d)))
|
.add_entity(EntityType::Dimension(Box::new(Dimension::Linear(d))))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
bake_dimension_blocks(&mut doc);
|
bake_dimension_blocks(&mut doc);
|
||||||
let name = match doc.get_entity(handle) {
|
let name = match doc.get_entity(handle) {
|
||||||
@@ -2064,7 +2064,7 @@ mod tests {
|
|||||||
DimensionLinear::new(Vector3::new(0.0, 0.0, 0.0), Vector3::new(10.0, 0.0, 0.0));
|
DimensionLinear::new(Vector3::new(0.0, 0.0, 0.0), Vector3::new(10.0, 0.0, 0.0));
|
||||||
d.definition_point = Vector3::new(0.0, 5.0, 0.0);
|
d.definition_point = Vector3::new(0.0, 5.0, 0.0);
|
||||||
d.base.text_middle_point = Vector3::new(5.0, 5.0, 0.0);
|
d.base.text_middle_point = Vector3::new(5.0, 5.0, 0.0);
|
||||||
doc.add_entity(EntityType::Dimension(Dimension::Linear(d)))
|
doc.add_entity(EntityType::Dimension(Box::new(Dimension::Linear(d))))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let path =
|
let path =
|
||||||
@@ -2171,7 +2171,7 @@ mod tests {
|
|||||||
d.base.text_middle_point = Vector3::new(5.0, 5.0, 0.0);
|
d.base.text_middle_point = Vector3::new(5.0, 5.0, 0.0);
|
||||||
d.base.common.xdictionary_handle = Some(dict_handle);
|
d.base.common.xdictionary_handle = Some(dict_handle);
|
||||||
let dim_handle = doc
|
let dim_handle = doc
|
||||||
.add_entity(EntityType::Dimension(Dimension::Linear(d)))
|
.add_entity(EntityType::Dimension(Box::new(Dimension::Linear(d))))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
bake_dimension_blocks(&mut doc);
|
bake_dimension_blocks(&mut doc);
|
||||||
|
|||||||
@@ -462,7 +462,7 @@ fn mtext_of_text(geom: &DgnGeom, color: u16) -> Option<EntityType> {
|
|||||||
m.rectangle_width = 0.0;
|
m.rectangle_width = 0.0;
|
||||||
m.drawing_direction = DrawingDirection::ByStyle;
|
m.drawing_direction = DrawingDirection::ByStyle;
|
||||||
m.style = "Standard".to_string();
|
m.style = "Standard".to_string();
|
||||||
Some(EntityType::MText(m))
|
Some(EntityType::MText(Box::new(m)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A text node as one MTEXT, a paragraph a line, attached at the node's
|
/// A text node as one MTEXT, a paragraph a line, attached at the node's
|
||||||
@@ -515,7 +515,7 @@ fn mtext_of_node(
|
|||||||
m.rectangle_width = 0.0;
|
m.rectangle_width = 0.0;
|
||||||
m.drawing_direction = DrawingDirection::ByStyle;
|
m.drawing_direction = DrawingDirection::ByStyle;
|
||||||
m.style = style;
|
m.style = style;
|
||||||
Some(EntityType::MText(m))
|
Some(EntityType::MText(Box::new(m)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An arc, circle or ellipse in its own plane.
|
/// An arc, circle or ellipse in its own plane.
|
||||||
|
|||||||
@@ -1482,7 +1482,7 @@ pub fn convert(
|
|||||||
let layer = naming.layer(pdf_layer, Kind::Text);
|
let layer = naming.layer(pdf_layer, Kind::Text);
|
||||||
mtext.common.color = color_on(&layer, color_of(text.color));
|
mtext.common.color = color_on(&layer, color_of(text.color));
|
||||||
mtext.common.layer = layer;
|
mtext.common.layer = layer;
|
||||||
result.entities.push(EntityType::MText(mtext));
|
result.entities.push(EntityType::MText(Box::new(mtext)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1712,7 +1712,7 @@ fn fill_entities(
|
|||||||
return Vec::new();
|
return Vec::new();
|
||||||
}
|
}
|
||||||
hatch.elevation = z;
|
hatch.elevation = z;
|
||||||
vec![EntityType::Hatch(hatch)]
|
vec![EntityType::Hatch(Box::new(hatch))]
|
||||||
}
|
}
|
||||||
|
|
||||||
inventory::submit!(crate::command::CommandRegistration {
|
inventory::submit!(crate::command::CommandRegistration {
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ impl MvsetupCommand {
|
|||||||
if self.arrangement == Arrangement::Engineering {
|
if self.arrangement == Arrangement::Engineering {
|
||||||
viewport.view_direction = directions[(row * 2 + column) as usize].clone();
|
viewport.view_direction = directions[(row * 2 + column) as usize].clone();
|
||||||
}
|
}
|
||||||
viewports.push(EntityType::Viewport(viewport));
|
viewports.push(EntityType::Viewport(Box::new(viewport)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CmdResult::CommitEntitiesAndExit(viewports)
|
CmdResult::CommitEntitiesAndExit(viewports)
|
||||||
|
|||||||
@@ -322,7 +322,7 @@ pub fn supports_annotation_context(entity: &EntityType) -> bool {
|
|||||||
| EntityType::Tolerance(_)
|
| EntityType::Tolerance(_)
|
||||||
| EntityType::Hatch(_) => true,
|
| EntityType::Hatch(_) => true,
|
||||||
EntityType::Dimension(dimension) => {
|
EntityType::Dimension(dimension) => {
|
||||||
!matches!(dimension, codec::entities::Dimension::Arc(_))
|
!matches!(&**dimension, codec::entities::Dimension::Arc(_))
|
||||||
}
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -788,7 +788,7 @@ mod tests {
|
|||||||
dimension.base.block_name = "SVC_TARGET".to_string();
|
dimension.base.block_name = "SVC_TARGET".to_string();
|
||||||
scene
|
scene
|
||||||
.document
|
.document
|
||||||
.add_entity(EntityType::Dimension(Dimension::Aligned(dimension)))
|
.add_entity(EntityType::Dimension(Box::new(Dimension::Aligned(dimension))))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// A table's picture block and a block-valued cell, by handle.
|
// A table's picture block and a block-valued cell, by handle.
|
||||||
@@ -894,7 +894,7 @@ mod tests {
|
|||||||
dimension.base.block_name = "SVC_RENAMED".to_string();
|
dimension.base.block_name = "SVC_RENAMED".to_string();
|
||||||
scene
|
scene
|
||||||
.document
|
.document
|
||||||
.add_entity(EntityType::Dimension(Dimension::Aligned(dimension)))
|
.add_entity(EntityType::Dimension(Box::new(Dimension::Aligned(dimension))))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let mut style = DimStyle::new("SVC_STYLE");
|
let mut style = DimStyle::new("SVC_STYLE");
|
||||||
style.dimblk = target;
|
style.dimblk = target;
|
||||||
|
|||||||
Vendored
+1
-1
@@ -747,7 +747,7 @@ fn tessellate_sub_local(
|
|||||||
// Sanity guard: skip sub-entities whose primary dimension is so large
|
// Sanity guard: skip sub-entities whose primary dimension is so large
|
||||||
// that adaptive tessellation will explode into hundreds of millions
|
// that adaptive tessellation will explode into hundreds of millions
|
||||||
// of points. These are typically corrupt-radius primitives that slipped
|
// of points. These are typically corrupt-radius primitives that slipped
|
||||||
// past purge_corrupt_entities (finite but absurd values).
|
// past the codec's unusable-geometry audit (finite but absurd values).
|
||||||
if is_unreasonable_extent(sub) {
|
if is_unreasonable_extent(sub) {
|
||||||
return vec![];
|
return vec![];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -479,7 +479,7 @@ impl Scene {
|
|||||||
self.previous_view = Some(ViewSnapshot::Floating {
|
self.previous_view = Some(ViewSnapshot::Floating {
|
||||||
layout,
|
layout,
|
||||||
handle,
|
handle,
|
||||||
viewport: Box::new(viewport.clone()),
|
viewport: viewport.clone(),
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -538,7 +538,7 @@ impl Scene {
|
|||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let current = Box::new(current.clone());
|
let current = current.clone();
|
||||||
if let Some(EntityType::Viewport(destination)) =
|
if let Some(EntityType::Viewport(destination)) =
|
||||||
self.document.get_entity_mut(handle)
|
self.document.get_entity_mut(handle)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -869,7 +869,7 @@ pub(crate) fn constraint_from_associative_dimension(
|
|||||||
Some(ParametricRef::whole(*reference.xrefs.first()?))
|
Some(ParametricRef::whole(*reference.xrefs.first()?))
|
||||||
};
|
};
|
||||||
let measurement = DrivingValue::Literal(dimension.measurement());
|
let measurement = DrivingValue::Literal(dimension.measurement());
|
||||||
match dimension {
|
match &**dimension {
|
||||||
Dimension::Aligned(_) => Some((
|
Dimension::Aligned(_) => Some((
|
||||||
ConstraintKind::Distance,
|
ConstraintKind::Distance,
|
||||||
vec![point(0)?, point(1)?],
|
vec![point(0)?, point(1)?],
|
||||||
@@ -921,7 +921,7 @@ pub(crate) fn radial_extension_points(
|
|||||||
let EntityType::Dimension(dimension_entity) = document.get_entity(dimension)? else {
|
let EntityType::Dimension(dimension_entity) = document.get_entity(dimension)? else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let target_point = match dimension_entity {
|
let target_point = match &**dimension_entity {
|
||||||
Dimension::Radius(radius) => radius.definition_point,
|
Dimension::Radius(radius) => radius.definition_point,
|
||||||
Dimension::Diameter(diameter) => diameter.angle_vertex,
|
Dimension::Diameter(diameter) => diameter.angle_vertex,
|
||||||
Dimension::LargeRadial(radial) => radial.chord_point,
|
Dimension::LargeRadial(radial) => radial.chord_point,
|
||||||
@@ -1009,7 +1009,7 @@ impl Scene {
|
|||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let radial_data = match dimension_entity {
|
let radial_data = match &**dimension_entity {
|
||||||
Dimension::Radius(radius) => Some((
|
Dimension::Radius(radius) => Some((
|
||||||
radius.angle_vertex,
|
radius.angle_vertex,
|
||||||
radius.measurement(),
|
radius.measurement(),
|
||||||
@@ -1223,7 +1223,7 @@ impl Scene {
|
|||||||
};
|
};
|
||||||
// Radial references identify a circle/arc and angle, rather than a vertex.
|
// Radial references identify a circle/arc and angle, rather than a vertex.
|
||||||
let radial_dimension = matches!(
|
let radial_dimension = matches!(
|
||||||
dimension_entity,
|
&**dimension_entity,
|
||||||
Dimension::Radius(_) | Dimension::Diameter(_) | Dimension::LargeRadial(_)
|
Dimension::Radius(_) | Dimension::Diameter(_) | Dimension::LargeRadial(_)
|
||||||
);
|
);
|
||||||
if radial_dimension {
|
if radial_dimension {
|
||||||
@@ -1383,7 +1383,7 @@ impl Scene {
|
|||||||
let Some(EntityType::Dimension(entity)) = self.document.get_entity(dimension) else {
|
let Some(EntityType::Dimension(entity)) = self.document.get_entity(dimension) else {
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
};
|
};
|
||||||
match entity {
|
match &**entity {
|
||||||
// A radial dimension's single reference describes the point where
|
// A radial dimension's single reference describes the point where
|
||||||
// the leader meets the circle.
|
// the leader meets the circle.
|
||||||
Dimension::Radius(radius) => vec![radius.definition_point],
|
Dimension::Radius(radius) => vec![radius.definition_point],
|
||||||
@@ -1458,17 +1458,15 @@ impl Scene {
|
|||||||
let measurement_supported = !association.trans_space
|
let measurement_supported = !association.trans_space
|
||||||
|| self.document.get_entity(dimension).is_some_and(|entity| {
|
|| self.document.get_entity(dimension).is_some_and(|entity| {
|
||||||
matches!(
|
matches!(
|
||||||
entity,
|
crate::entities::dimension::as_dimension(entity),
|
||||||
EntityType::Dimension(Dimension::Angular2Ln(_) | Dimension::Angular3Pt(_))
|
Some(Dimension::Angular2Ln(_) | Dimension::Angular3Pt(_))
|
||||||
) || persisted_measurement_scale(&self.document, entity).is_some()
|
) || persisted_measurement_scale(&self.document, entity).is_some()
|
||||||
});
|
});
|
||||||
let measurement_supported = measurement_supported
|
let measurement_supported = measurement_supported
|
||||||
&& self.document.get_entity(dimension).is_some_and(|entity| {
|
&& self.document.get_entity(dimension).is_some_and(|entity| {
|
||||||
if !matches!(
|
if !matches!(
|
||||||
entity,
|
crate::entities::dimension::as_dimension(entity),
|
||||||
EntityType::Dimension(
|
Some(Dimension::Radius(_) | Dimension::Diameter(_) | Dimension::LargeRadial(_))
|
||||||
Dimension::Radius(_) | Dimension::Diameter(_) | Dimension::LargeRadial(_)
|
|
||||||
)
|
|
||||||
) {
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1652,7 +1650,7 @@ impl Scene {
|
|||||||
let Some(EntityType::Dimension(entity)) = self.document.get_entity(dimension) else {
|
let Some(EntityType::Dimension(entity)) = self.document.get_entity(dimension) else {
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
};
|
};
|
||||||
let radial_data = match entity {
|
let radial_data = match &**entity {
|
||||||
Dimension::Radius(radius) => Some((
|
Dimension::Radius(radius) => Some((
|
||||||
radius.angle_vertex,
|
radius.angle_vertex,
|
||||||
radius.measurement(),
|
radius.measurement(),
|
||||||
@@ -1850,8 +1848,8 @@ impl Scene {
|
|||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let angular = matches!(
|
let angular = matches!(
|
||||||
&before,
|
crate::entities::dimension::as_dimension(&before),
|
||||||
EntityType::Dimension(Dimension::Angular2Ln(_) | Dimension::Angular3Pt(_))
|
Some(Dimension::Angular2Ln(_) | Dimension::Angular3Pt(_))
|
||||||
);
|
);
|
||||||
let measurement_scale = if let Some(frame) = map.frame.filter(|_| !angular) {
|
let measurement_scale = if let Some(frame) = map.frame.filter(|_| !angular) {
|
||||||
let Some(mut scale) = persisted_measurement_scale(&self.document, &before) else {
|
let Some(mut scale) = persisted_measurement_scale(&self.document, &before) else {
|
||||||
@@ -1874,7 +1872,7 @@ impl Scene {
|
|||||||
else {
|
else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
match dimension {
|
match &mut **dimension {
|
||||||
Dimension::Linear(linear) => {
|
Dimension::Linear(linear) => {
|
||||||
// The sheet annotation the user placed — the dimension
|
// The sheet annotation the user placed — the dimension
|
||||||
// line's standoff and, when they dragged it, the text — is
|
// line's standoff and, when they dragged it, the text — is
|
||||||
@@ -2104,7 +2102,7 @@ impl Scene {
|
|||||||
arc.base.actual_measurement = arc.measurement();
|
arc.base.actual_measurement = arc.measurement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let measurement = match &*dimension {
|
let measurement = match &**dimension {
|
||||||
Dimension::Linear(linear) => linear_measurement(linear),
|
Dimension::Linear(linear) => linear_measurement(linear),
|
||||||
_ => dimension.measurement(),
|
_ => dimension.measurement(),
|
||||||
};
|
};
|
||||||
@@ -2155,8 +2153,12 @@ impl Scene {
|
|||||||
refreshed
|
refreshed
|
||||||
}
|
}
|
||||||
pub(crate) fn sync_diameter_association_angle(&mut self, dimension: Handle) {
|
pub(crate) fn sync_diameter_association_angle(&mut self, dimension: Handle) {
|
||||||
let chord = match self.document.get_entity(dimension) {
|
let chord = match self
|
||||||
Some(EntityType::Dimension(Dimension::Diameter(diameter))) => diameter.angle_vertex,
|
.document
|
||||||
|
.get_entity(dimension)
|
||||||
|
.and_then(crate::entities::dimension::as_dimension)
|
||||||
|
{
|
||||||
|
Some(Dimension::Diameter(diameter)) => diameter.angle_vertex,
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2247,9 +2249,9 @@ mod tests {
|
|||||||
Vector3::ZERO,
|
Vector3::ZERO,
|
||||||
5.0,
|
5.0,
|
||||||
)));
|
)));
|
||||||
let dimension = scene.add_entity(EntityType::Dimension(Dimension::Diameter(
|
let dimension = scene.add_entity(EntityType::Dimension(Box::new(Dimension::Diameter(
|
||||||
DimensionDiameter::new(Vector3::new(5.0, 0.0, 0.0), Vector3::new(-5.0, 0.0, 0.0)),
|
DimensionDiameter::new(Vector3::new(5.0, 0.0, 0.0), Vector3::new(-5.0, 0.0, 0.0)),
|
||||||
)));
|
))));
|
||||||
scene.attach_dimension_association(dimension, vec![Some(circle)]);
|
scene.attach_dimension_association(dimension, vec![Some(circle)]);
|
||||||
let association = scene
|
let association = scene
|
||||||
.document
|
.document
|
||||||
@@ -2270,8 +2272,10 @@ mod tests {
|
|||||||
.expect("diameter association");
|
.expect("diameter association");
|
||||||
|
|
||||||
scene.begin_undo_recording();
|
scene.begin_undo_recording();
|
||||||
let Some(EntityType::Dimension(Dimension::Diameter(diameter))) =
|
let Some(Dimension::Diameter(diameter)) = scene
|
||||||
scene.document.get_entity_mut(dimension)
|
.document
|
||||||
|
.get_entity_mut(dimension)
|
||||||
|
.and_then(crate::entities::dimension::as_dimension_mut)
|
||||||
else {
|
else {
|
||||||
panic!("diameter dimension");
|
panic!("diameter dimension");
|
||||||
};
|
};
|
||||||
|
|||||||
+1
-1
@@ -3206,7 +3206,7 @@ impl Scene {
|
|||||||
if let Some(origin) = model.pattern_origin {
|
if let Some(origin) = model.pattern_origin {
|
||||||
dxf.record_pattern_origin(Vector2::new(origin[0], origin[1]));
|
dxf.record_pattern_origin(Vector2::new(origin[0], origin[1]));
|
||||||
}
|
}
|
||||||
let mut entity = EntityType::Hatch(dxf);
|
let mut entity = EntityType::Hatch(Box::new(dxf));
|
||||||
|
|
||||||
if let Some(layer) = layer {
|
if let Some(layer) = layer {
|
||||||
entity.as_entity_mut().set_layer(layer.to_string());
|
entity.as_entity_mut().set_layer(layer.to_string());
|
||||||
|
|||||||
Loaded 100 of 119 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user