forked from 1b-agent/opencadstudio-upstream
Merge pull request #890 from ramox81/codex/fix-jogged-radius-properties
Fix jogged radius properties and layout
This commit is contained in:
6 files changed
+1113
-608
No files matched your search
@@ -1063,16 +1063,6 @@ impl OpenCADStudio {
|
||||
&self.tabs[i].scene.document,
|
||||
));
|
||||
|
||||
if matches!(d, acadrust::entities::Dimension::LargeRadial(_)) {
|
||||
if let Some(index) = sections
|
||||
.iter()
|
||||
.position(|section| section.title == t!("Misc").as_ref())
|
||||
{
|
||||
let misc = sections.remove(index);
|
||||
sections.push(misc);
|
||||
}
|
||||
}
|
||||
|
||||
// Prefer entity-level dimension-variable overrides;
|
||||
// fall back to the assigned style values.
|
||||
use crate::entities::dim_override as dov;
|
||||
|
||||
@@ -1981,12 +1981,20 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
||||
self.tabs[i].scene.document.get_entity(handle),
|
||||
Some(acadrust::EntityType::Dimension(_))
|
||||
) {
|
||||
crate::entities::dim_override::set_property(
|
||||
let applied = crate::entities::dim_override::set_property(
|
||||
&mut self.tabs[i].scene.document,
|
||||
handle,
|
||||
field,
|
||||
&value,
|
||||
);
|
||||
if applied && field == "dim_text_inside" {
|
||||
if let Some(acadrust::EntityType::Dimension(
|
||||
acadrust::entities::Dimension::LargeRadial(dimension),
|
||||
)) = self.tabs[i].scene.document.get_entity_mut(handle)
|
||||
{
|
||||
dimension.base.text_user_positioned = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if field == "vscale_std" {
|
||||
@@ -2403,6 +2411,13 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
||||
}
|
||||
_ => None,
|
||||
});
|
||||
if matches!(field, "text_x" | "text_y") {
|
||||
crate::entities::dimension::materialize_large_radial_text_position(
|
||||
&mut self.tabs[i].scene.document,
|
||||
handle,
|
||||
&value,
|
||||
);
|
||||
}
|
||||
if let Some(entity) = self.tabs[i].scene.document.get_entity_mut(handle)
|
||||
{
|
||||
crate::scene::view::dispatch::apply_geom_prop_in_working_plane(
|
||||
@@ -2649,12 +2664,25 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
||||
self.tabs[i].scene.document.get_entity(handle),
|
||||
Some(acadrust::EntityType::Dimension(_))
|
||||
) {
|
||||
crate::entities::dim_override::set_property(
|
||||
let applied = crate::entities::dim_override::set_property(
|
||||
&mut self.tabs[i].scene.document,
|
||||
handle,
|
||||
field,
|
||||
&val,
|
||||
);
|
||||
if applied && field == "dim_text_inside" {
|
||||
if let Some(acadrust::EntityType::Dimension(
|
||||
acadrust::entities::Dimension::LargeRadial(
|
||||
dimension,
|
||||
),
|
||||
)) = self.tabs[i]
|
||||
.scene
|
||||
.document
|
||||
.get_entity_mut(handle)
|
||||
{
|
||||
dimension.base.text_user_positioned = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"hyperlink" => {
|
||||
@@ -2751,6 +2779,13 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
||||
}
|
||||
_ => None,
|
||||
});
|
||||
if matches!(field, "text_x" | "text_y") {
|
||||
crate::entities::dimension::materialize_large_radial_text_position(
|
||||
&mut self.tabs[i].scene.document,
|
||||
handle,
|
||||
&val,
|
||||
);
|
||||
}
|
||||
if let Some(entity) = self.tabs[i]
|
||||
.scene
|
||||
.document
|
||||
|
||||
@@ -403,8 +403,8 @@ pub fn set_property(
|
||||
let size = current.abs().max(0.01);
|
||||
let value = match trimmed.to_ascii_lowercase().as_str() {
|
||||
"none" => 0.0,
|
||||
"center marks" => size,
|
||||
"centerlines" => -size,
|
||||
"mark" | "center marks" => size,
|
||||
"line" | "centerlines" => -size,
|
||||
_ => return false,
|
||||
};
|
||||
set(doc, handle, DIMCEN, Some(XDataValue::Real(value)));
|
||||
@@ -423,6 +423,7 @@ pub fn set_property(
|
||||
return true;
|
||||
}
|
||||
let handle_field = match field {
|
||||
"dim_radial_arrow" => Some(DIMLDRBLK),
|
||||
"dim_arrowhead_1" => Some(DIMBLK1),
|
||||
"dim_arrowhead_2" => Some(DIMBLK2),
|
||||
"dim_linetype" => Some(DIMLTYPE),
|
||||
@@ -433,7 +434,7 @@ pub fn set_property(
|
||||
};
|
||||
if let Some(code) = handle_field {
|
||||
let resolved = match field {
|
||||
"dim_arrowhead_1" | "dim_arrowhead_2" => {
|
||||
"dim_radial_arrow" | "dim_arrowhead_1" | "dim_arrowhead_2" => {
|
||||
if trimmed == "Closed filled" {
|
||||
Some(Handle::NULL)
|
||||
} else {
|
||||
@@ -638,6 +639,10 @@ pub fn set_property(
|
||||
"dim_line_lineweight" | "dim_ext_line_lineweight" => {
|
||||
parse_lineweight_label(trimmed)
|
||||
}
|
||||
"dim_precision"
|
||||
| "dim_alt_precision"
|
||||
| "dim_tolerance_precision"
|
||||
| "dim_alt_tolerance_precision" => parse_precision_label(trimmed),
|
||||
"dim_ext_line_fixed"
|
||||
| "dim_text_outside_align"
|
||||
| "dim_text_inside_align"
|
||||
@@ -729,8 +734,8 @@ pub fn set_property(
|
||||
_ => trimmed.parse().ok(),
|
||||
},
|
||||
"dim_tolerance_alignment" => match trimmed.to_ascii_lowercase().as_str() {
|
||||
"align decimal separators" => Some(0),
|
||||
"align operational symbols" => Some(1),
|
||||
"decimal separator" | "align decimal separators" => Some(0),
|
||||
"operational symbols" | "align operational symbols" => Some(1),
|
||||
_ => trimmed.parse().ok(),
|
||||
},
|
||||
_ => trimmed.parse().ok(),
|
||||
@@ -744,6 +749,16 @@ pub fn set_property(
|
||||
false
|
||||
}
|
||||
|
||||
fn parse_precision_label(value: &str) -> Option<i16> {
|
||||
if let Some(decimals) = value.strip_prefix("0.") {
|
||||
return (!decimals.is_empty()
|
||||
&& decimals.len() <= 8
|
||||
&& decimals.bytes().all(|digit| digit == b'0'))
|
||||
.then_some(decimals.len() as i16);
|
||||
}
|
||||
value.parse().ok()
|
||||
}
|
||||
|
||||
fn parse_lineweight_label(value: &str) -> Option<i16> {
|
||||
match value.trim() {
|
||||
"ByLayer" => Some(-1),
|
||||
|
||||
+982
-396
File diff suppressed because it is too large.
Load diff
@@ -356,6 +356,38 @@ fn dim_seg(a: Vector3, b: Vector3, common: &acadrust::entities::EntityCommon) ->
|
||||
})
|
||||
}
|
||||
|
||||
fn dim_geom_entities(
|
||||
geometry: &crate::scene::convert::tessellate::DimGeom,
|
||||
ext_common: &acadrust::entities::EntityCommon,
|
||||
dim_common: &acadrust::entities::EntityCommon,
|
||||
) -> Vec<EntityType> {
|
||||
let mut entities = Vec::new();
|
||||
let point = |value: [f32; 3]| {
|
||||
Vector3::new(value[0] as f64, value[1] as f64, value[2] as f64)
|
||||
};
|
||||
for (points, common) in [
|
||||
(geometry.ext_lines.as_slice(), ext_common),
|
||||
(geometry.dim_lines.as_slice(), dim_common),
|
||||
] {
|
||||
for run in points.split(|point| point[0].is_nan()) {
|
||||
for pair in run.windows(2) {
|
||||
entities.push(dim_seg(point(pair[0]), point(pair[1]), common));
|
||||
}
|
||||
}
|
||||
}
|
||||
for triangle in geometry.arrow_fill.chunks_exact(3) {
|
||||
let mut solid = acadrust::entities::Solid::triangle(
|
||||
point(triangle[0]),
|
||||
point(triangle[1]),
|
||||
point(triangle[2]),
|
||||
);
|
||||
solid.common = dim_common.clone();
|
||||
solid.common.handle = Handle::NULL;
|
||||
entities.push(EntityType::Solid(solid));
|
||||
}
|
||||
entities
|
||||
}
|
||||
|
||||
/// A dimension-line terminator at `tip`, body extending back along the unit
|
||||
/// vector `(dx,dy)` (toward the dim line). When DIMTSZ>0 it's an oblique 45°
|
||||
/// tick; otherwise a closed *filled* arrowhead (DXF SOLID) of length DIMASZ —
|
||||
@@ -597,80 +629,23 @@ struct DimMetrics {
|
||||
dimclrt: i16,
|
||||
dimlwd: i16,
|
||||
dimlwe: i16,
|
||||
/// Resolved terminator shapes for the first / second end (DIMTSZ tick,
|
||||
/// DIMBLK/DIMBLK1/DIMBLK2 per DIMSAH, else closed-filled), so the bake
|
||||
/// reproduces the style's actual arrow type.
|
||||
dimltype: Handle,
|
||||
dimltex1: Handle,
|
||||
arrow1: crate::scene::convert::tessellate::ArrowKind,
|
||||
arrow2: crate::scene::convert::tessellate::ArrowKind,
|
||||
}
|
||||
|
||||
/// Metrics from the dim's style, mirroring what the live renderer applies, so a
|
||||
/// baked block reproduces the same gaps, arrow type, suppression, colours and
|
||||
/// lineweights: DIMASZ (arrow), DIMCEN (centre mark), DIMEXO/DIMEXE (extension
|
||||
/// gap/overshoot), DIMTSZ (oblique tick; >0 = ticks not arrows), DIMDLE (dim
|
||||
/// line overshoot past ticks), DIMSE1/2 + DIMSD1/2 (extension / dim-line
|
||||
/// suppression), DIMCLRD/E/T (colours) and DIMLWD/E (lineweights).
|
||||
/// Resolve style metrics used by saved dimension geometry.
|
||||
fn dim_metrics(dim: &Dimension, doc: &CadDocument) -> DimMetrics {
|
||||
let name = dim.base().style_name.as_str();
|
||||
let mut effective_style = doc.dim_styles.iter().find(|s| {
|
||||
s.name.eq_ignore_ascii_case(name)
|
||||
|| (name.trim().is_empty() && s.name.eq_ignore_ascii_case("Standard"))
|
||||
}).cloned();
|
||||
if let Some(style) = &mut effective_style {
|
||||
use crate::entities::dim_override as ov;
|
||||
let data = &dim.base().common.extended_data;
|
||||
macro_rules! real {
|
||||
($field:ident, $code:ident) => {
|
||||
if let Some(value) = ov::real(data, ov::$code) {
|
||||
style.$field = value;
|
||||
}
|
||||
};
|
||||
}
|
||||
macro_rules! int {
|
||||
($field:ident, $code:ident) => {
|
||||
if let Some(value) = ov::int(data, ov::$code) {
|
||||
style.$field = value;
|
||||
}
|
||||
};
|
||||
}
|
||||
macro_rules! flag {
|
||||
($field:ident, $code:ident) => {
|
||||
if let Some(value) = ov::int(data, ov::$code) {
|
||||
style.$field = value != 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
macro_rules! handle {
|
||||
($field:ident, $code:ident) => {
|
||||
if let Some(value) = ov::handle(data, ov::$code) {
|
||||
style.$field = value;
|
||||
}
|
||||
};
|
||||
}
|
||||
real!(dimscale, DIMSCALE);
|
||||
real!(dimasz, DIMASZ);
|
||||
real!(dimcen, DIMCEN);
|
||||
real!(dimexo, DIMEXO);
|
||||
real!(dimexe, DIMEXE);
|
||||
real!(dimtsz, DIMTSZ);
|
||||
real!(dimdle, DIMDLE);
|
||||
real!(dimfxl, DIMFXL);
|
||||
flag!(dimfxlon, DIMFXLON);
|
||||
flag!(dimse1, DIMSE1);
|
||||
flag!(dimse2, DIMSE2);
|
||||
flag!(dimsd1, DIMSD1);
|
||||
flag!(dimsd2, DIMSD2);
|
||||
flag!(dimsoxd, DIMSOXD);
|
||||
flag!(dimsah, DIMSAH);
|
||||
int!(dimclrd, DIMCLRD);
|
||||
int!(dimclre, DIMCLRE);
|
||||
int!(dimclrt, DIMCLRT);
|
||||
int!(dimlwd, DIMLWD);
|
||||
int!(dimlwe, DIMLWE);
|
||||
handle!(dimblk, DIMBLK);
|
||||
handle!(dimblk1, DIMBLK1);
|
||||
handle!(dimblk2, DIMBLK2);
|
||||
}
|
||||
let effective_style = doc
|
||||
.dim_styles
|
||||
.iter()
|
||||
.find(|style| {
|
||||
style.name.eq_ignore_ascii_case(name)
|
||||
|| (name.trim().is_empty() && style.name.eq_ignore_ascii_case("Standard"))
|
||||
})
|
||||
.map(|style| crate::entities::dimension::resolved_dimension_style(style, dim, doc));
|
||||
let style = effective_style.as_ref();
|
||||
let scale = style
|
||||
.map(|s| if s.dimscale > 1e-6 { s.dimscale } else { 1.0 })
|
||||
@@ -679,14 +654,14 @@ fn dim_metrics(dim: &Dimension, doc: &CadDocument) -> DimMetrics {
|
||||
let dimasz = style.map(|s| s.dimasz * scale).unwrap_or(0.18 * scale).max(1e-6);
|
||||
let dimtsz = style.map(|s| s.dimtsz * scale).unwrap_or(0.0);
|
||||
let asz = dimasz as f32;
|
||||
// Resolve the terminator shapes exactly like the live render: ticks when
|
||||
// DIMTSZ>0, otherwise the DIMBLK / DIMBLK1+DIMBLK2 (per DIMSAH) arrow blocks,
|
||||
// else closed-filled.
|
||||
let (arrow1, arrow2) = if dimtsz > 1e-9 {
|
||||
let t = ArrowKind::Tick { size: dimtsz as f32 };
|
||||
(t.clone(), t)
|
||||
} else if let Some(s) = style {
|
||||
if matches!(dim, Dimension::Diameter(_)) {
|
||||
if matches!(dim, Dimension::Radius(_) | Dimension::LargeRadial(_)) {
|
||||
let arrow = arrow_from_block(doc, s.dimldrblk, asz);
|
||||
(arrow.clone(), arrow)
|
||||
} else if matches!(dim, Dimension::Diameter(_)) {
|
||||
use crate::entities::dim_override as ov;
|
||||
let data = &dim.base().common.extended_data;
|
||||
let first = ov::handle(data, ov::DIMBLK1)
|
||||
@@ -723,6 +698,8 @@ fn dim_metrics(dim: &Dimension, doc: &CadDocument) -> DimMetrics {
|
||||
dimclrt: style.map(|s| s.dimclrt).unwrap_or(0),
|
||||
dimlwd: style.map(|s| s.dimlwd).unwrap_or(-2),
|
||||
dimlwe: style.map(|s| s.dimlwe).unwrap_or(-2),
|
||||
dimltype: style.map(|s| s.dimltex_handle).unwrap_or(Handle::NULL),
|
||||
dimltex1: style.map(|s| s.dimltex1_handle).unwrap_or(Handle::NULL),
|
||||
arrow1,
|
||||
arrow2,
|
||||
}
|
||||
@@ -744,6 +721,21 @@ fn dim_common(base: &acadrust::entities::EntityCommon, clr: i16, lw: i16) -> aca
|
||||
c
|
||||
}
|
||||
|
||||
fn with_dim_linetype(
|
||||
mut common: acadrust::entities::EntityCommon,
|
||||
doc: &CadDocument,
|
||||
handle: Handle,
|
||||
) -> acadrust::entities::EntityCommon {
|
||||
common.linetype = doc
|
||||
.line_types
|
||||
.iter()
|
||||
.find(|line_type| line_type.handle == handle)
|
||||
.map(|line_type| line_type.name.clone())
|
||||
.unwrap_or_else(|| "Continuous".to_string());
|
||||
common.linetype_handle = (!handle.is_null()).then_some(handle);
|
||||
common
|
||||
}
|
||||
|
||||
/// Baked geometry for an angular dimension, matching the live render exactly:
|
||||
/// an extension line from each measured ray point flush out to the dimension
|
||||
/// arc, the swept arc, and a terminator at each arc end. (The live angular path
|
||||
@@ -806,49 +798,6 @@ fn angular_block_segs(
|
||||
out
|
||||
}
|
||||
|
||||
fn jogged_radial_break(
|
||||
chord: Vector3,
|
||||
jog: Vector3,
|
||||
override_center: Vector3,
|
||||
jog_angle: f64,
|
||||
) -> (Vector3, Vector3) {
|
||||
let radial = norm2(
|
||||
chord.x - override_center.x,
|
||||
chord.y - override_center.y,
|
||||
1.0,
|
||||
0.0,
|
||||
);
|
||||
let (sin, cos) = jog_angle.sin_cos();
|
||||
let transverse = (
|
||||
radial.0 * cos - radial.1 * sin,
|
||||
radial.0 * sin + radial.1 * cos,
|
||||
);
|
||||
let length = ((chord.x - override_center.x).powi(2)
|
||||
+ (chord.y - override_center.y).powi(2))
|
||||
.sqrt();
|
||||
let half = (length * 0.04).max(1e-6);
|
||||
let first = Vector3::new(
|
||||
jog.x - transverse.0 * half,
|
||||
jog.y - transverse.1 * half,
|
||||
jog.z,
|
||||
);
|
||||
let second = Vector3::new(
|
||||
jog.x + transverse.0 * half,
|
||||
jog.y + transverse.1 * half,
|
||||
jog.z,
|
||||
);
|
||||
let distance_squared = |point: Vector3| {
|
||||
(point.x - chord.x).powi(2)
|
||||
+ (point.y - chord.y).powi(2)
|
||||
+ (point.z - chord.z).powi(2)
|
||||
};
|
||||
if distance_squared(first) <= distance_squared(second) {
|
||||
(first, second)
|
||||
} else {
|
||||
(second, first)
|
||||
}
|
||||
}
|
||||
|
||||
/// The text anchor for a radial leader: the saved text middle point when set,
|
||||
/// else the midpoint of `a` and `b` — mirroring the live `dimension_text_position`.
|
||||
fn dim_text_anchor(
|
||||
@@ -1246,38 +1195,14 @@ fn explode_dimension(dim: &Dimension, doc: &CadDocument) -> Vec<EntityType> {
|
||||
));
|
||||
}
|
||||
}
|
||||
Dimension::LargeRadial(d) => {
|
||||
let (near, far) = jogged_radial_break(
|
||||
d.chord_point,
|
||||
d.jog_point,
|
||||
d.override_center,
|
||||
d.jog_angle,
|
||||
);
|
||||
if !met.dimsd1 {
|
||||
result.push(make_seg(&d.chord_point, &near, &dim_c));
|
||||
result.push(make_seg(&near, &far, &dim_c));
|
||||
result.push(make_seg(&far, &d.override_center, &dim_c));
|
||||
Dimension::LargeRadial(_) => {
|
||||
if let Some(geometry) =
|
||||
crate::entities::dimension::baked_large_radial_geometry(dim, doc)
|
||||
{
|
||||
let radial_ext_c = with_dim_linetype(ext_c.clone(), doc, met.dimltex1);
|
||||
let radial_dim_c = with_dim_linetype(dim_c.clone(), doc, met.dimltype);
|
||||
result.extend(dim_geom_entities(&geometry, &radial_ext_c, &radial_dim_c));
|
||||
}
|
||||
let len = ((near.x - d.chord_point.x).powi(2)
|
||||
+ (near.y - d.chord_point.y).powi(2))
|
||||
.sqrt()
|
||||
.max(1e-12);
|
||||
result.extend(dim_terminator(
|
||||
d.chord_point,
|
||||
(near.x - d.chord_point.x) / len,
|
||||
(near.y - d.chord_point.y) / len,
|
||||
&met.arrow1,
|
||||
&dim_c,
|
||||
));
|
||||
let radius = ((d.definition_point.x - d.chord_point.x).powi(2)
|
||||
+ (d.definition_point.y - d.chord_point.y).powi(2))
|
||||
.sqrt();
|
||||
result.extend(dim_center_mark(
|
||||
d.definition_point,
|
||||
met.dimcen,
|
||||
radius,
|
||||
&dim_c,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1371,23 +1296,7 @@ fn next_dimension_block_name(doc: &CadDocument, next: &mut u64) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
/// Bake an anonymous `*D<n>` geometry block for every DIMENSION that doesn't
|
||||
/// already own one, so the file is valid for AutoCAD-family readers.
|
||||
///
|
||||
/// OCS renders dimensions by re-tessellating them on the fly and never
|
||||
/// materialises the `*D` block that a DWG `DIMENSION` is supposed to reference
|
||||
/// (the lines / arrows / text that AutoCAD actually draws). A dimension created
|
||||
/// in OCS therefore goes out referencing a block that doesn't exist, and the
|
||||
/// writer emits a null block handle — strict readers (DWG TrueView, QCAD) drop
|
||||
/// the dimension or demand a recovery, and lenient ones (BricsCAD) regenerate it
|
||||
/// at a different position. Call this on the document about to be written so each
|
||||
/// such dimension gets a real block built from its exploded geometry (extension
|
||||
/// lines + dimension line + measurement text, the same decomposition EXPLODE
|
||||
/// uses) and its `block_name` points at it.
|
||||
///
|
||||
/// Dimensions that already reference an existing block (e.g. imported from a real
|
||||
/// DWG, or copied via the `*D`-cloning copy path) are left untouched so their
|
||||
/// original graphics are preserved.
|
||||
/// Build missing anonymous dimension geometry blocks before writing.
|
||||
pub fn bake_dimension_blocks(doc: &mut CadDocument) {
|
||||
// Keep group-10 in step and find missing blocks in one entity pass. Existing
|
||||
// `*D` blocks are the save cache: only invalidated/new dimensions enter the
|
||||
@@ -1451,35 +1360,13 @@ pub fn bake_dimension_blocks(doc: &mut CadDocument) {
|
||||
|
||||
if let Some(EntityType::Dimension(d)) = doc.get_entity_mut(handle) {
|
||||
d.base_mut().block_name = name;
|
||||
// The block we just baked holds the dimension graphics in absolute
|
||||
// WCS, so the DWG group-12 insertion point (base.insertion_point)
|
||||
// MUST be the origin. A reader that positions the *D block by that
|
||||
// point (BricsCAD / ODA) otherwise draws it shifted by the offset,
|
||||
// while OCS — which renders the block in place — shows it correctly.
|
||||
// OCS's dimension commands seed insertion_point with the text
|
||||
// anchor; reset it here so the saved dimension lands identically in
|
||||
// every application. (#181)
|
||||
// Baked geometry uses absolute coordinates.
|
||||
d.base_mut().insertion_point = Vector3::new(0.0, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Drop a dimension's baked `*D` block so the next save regenerates it from the
|
||||
/// dimension's current definition points / text / style.
|
||||
///
|
||||
/// OCS renders a dimension live from its definition points, but exports a baked
|
||||
/// `*D` block that other applications (BricsCAD / ODA) draw instead. An in-place
|
||||
/// edit — grip drag, DIMTEDIT, restyle, text edit, DIMSPACE — changes the
|
||||
/// definition points while leaving the old block, so without this the export
|
||||
/// keeps the pre-edit graphics and the dimension appears wrong everywhere but in
|
||||
/// OCS. Call this after any such edit; [`bake_dimension_blocks`] then rebuilds a
|
||||
/// fresh block on save.
|
||||
///
|
||||
/// The transform path (MOVE / COPY / PASTE) keeps its own block in sync via
|
||||
/// `define_transformed_block` and must NOT call this. The removed block's record
|
||||
/// and owned entities are deleted too, so re-baking on every edit can't
|
||||
/// accumulate orphan `*D` blocks. No-op when the dimension has no baked block
|
||||
/// yet (the pending path bakes it fresh on save). (#181)
|
||||
/// Drop baked dimension geometry so the next save regenerates it.
|
||||
pub fn invalidate_dim_block(doc: &mut CadDocument, handle: Handle) {
|
||||
let bn = match doc.get_entity(handle) {
|
||||
Some(EntityType::Dimension(d)) => d.base().block_name.clone(),
|
||||
|
||||
Vendored
-8
@@ -89,14 +89,6 @@ pub fn general_section(entity: &EntityType) -> PropSection {
|
||||
],
|
||||
};
|
||||
|
||||
if matches!(entity, EntityType::Point(_)) {
|
||||
let hyperlink = section.props.iter().position(|prop| prop.field == "hyperlink");
|
||||
let transparency = section.props.iter().position(|prop| prop.field == "transparency");
|
||||
if let (Some(hyperlink), Some(transparency)) = (hyperlink, transparency) {
|
||||
section.props.swap(hyperlink, transparency);
|
||||
}
|
||||
}
|
||||
|
||||
// Thickness (DXF 39) is a General-group property, but only the entity
|
||||
// types that carry an extrusion thickness expose it (line, circle, arc,
|
||||
// polyline, text, 2D solid, …). Show it right after Hyperlink for those.
|
||||
|
||||
Reference in new issue
Block a user