forked from 1b-agent/opencadstudio-upstream
feat(styles): overhaul style managers
Unify editor layouts, live previews, comparisons, read-only behavior, and localized controls across all named style managers. Refs #629
This commit is contained in:
1 parent
d06a1022f2
commit
25515fa33c
27 files changed
+5506
-1662
No files matched your search
@@ -1538,28 +1538,6 @@ pub(crate) fn arrow_from_block(
|
||||
.unwrap_or_else(|| arrow_from_block_name(None, dimasz))
|
||||
}
|
||||
|
||||
pub(crate) fn arrow_block_is_custom(
|
||||
doc: &CadDocument,
|
||||
handle: acadrust::types::Handle,
|
||||
) -> bool {
|
||||
if handle.is_null() {
|
||||
return false;
|
||||
}
|
||||
doc.block_records
|
||||
.iter()
|
||||
.find(|record| record.handle == handle)
|
||||
.is_some_and(|record| {
|
||||
!record.entity_handles.is_empty()
|
||||
&& !record.is_layout()
|
||||
&& !record.is_model_space()
|
||||
&& !record.is_paper_space()
|
||||
&& !record.flags.is_xref
|
||||
&& !record.flags.is_xref_overlay
|
||||
&& !record.flags.is_external
|
||||
&& builtin_arrow_from_block_name(&record.name, 1.0).is_none()
|
||||
})
|
||||
}
|
||||
|
||||
fn arrow_from_block_name(name: Option<&str>, dimasz: f32) -> ArrowKind {
|
||||
name.and_then(|name| builtin_arrow_from_block_name(name, dimasz))
|
||||
.unwrap_or(ArrowKind::Triangle {
|
||||
@@ -1742,6 +1720,10 @@ fn collect_custom_arrow_entity(
|
||||
stack.pop();
|
||||
return;
|
||||
}
|
||||
EntityType::Hatch(hatch) => {
|
||||
append_custom_hatch_fill(hatch, root_base, fill);
|
||||
return;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
@@ -1766,6 +1748,69 @@ fn collect_custom_arrow_entity(
|
||||
}
|
||||
}
|
||||
|
||||
fn append_custom_hatch_fill(
|
||||
hatch: &acadrust::entities::Hatch,
|
||||
base: acadrust::types::Vector3,
|
||||
out: &mut Vec<[f32; 3]>,
|
||||
) {
|
||||
use lyon_tessellation::math::point;
|
||||
use lyon_tessellation::path::Path;
|
||||
use lyon_tessellation::{
|
||||
BuffersBuilder, FillOptions, FillRule, FillTessellator, FillVertex, VertexBuffers,
|
||||
};
|
||||
|
||||
let Some(model) = crate::scene::Scene::hatch_model_from_dxf(hatch, [1.0; 4]) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let mut builder = Path::builder();
|
||||
let mut ring: Vec<[f32; 2]> = Vec::new();
|
||||
let mut finish_ring = |ring: &mut Vec<[f32; 2]>| {
|
||||
if ring.len() >= 3 {
|
||||
builder.begin(point(ring[0][0], ring[0][1]));
|
||||
for p in &ring[1..] {
|
||||
builder.line_to(point(p[0], p[1]));
|
||||
}
|
||||
builder.end(true);
|
||||
}
|
||||
ring.clear();
|
||||
};
|
||||
for &[x, y] in model.boundary.iter() {
|
||||
if x.is_nan() || y.is_nan() {
|
||||
finish_ring(&mut ring);
|
||||
continue;
|
||||
}
|
||||
ring.push([
|
||||
(model.world_origin[0] + x as f64 - base.x) as f32,
|
||||
(model.world_origin[1] + y as f64 - base.y) as f32,
|
||||
]);
|
||||
}
|
||||
finish_ring(&mut ring);
|
||||
|
||||
let mut geometry: VertexBuffers<[f32; 2], u32> = VertexBuffers::new();
|
||||
let mut tessellator = FillTessellator::new();
|
||||
if tessellator
|
||||
.tessellate_path(
|
||||
&builder.build(),
|
||||
&FillOptions::default().with_fill_rule(FillRule::EvenOdd),
|
||||
&mut BuffersBuilder::new(&mut geometry, |vertex: FillVertex| {
|
||||
vertex.position().to_array()
|
||||
}),
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
return;
|
||||
}
|
||||
let z = -base.z as f32;
|
||||
out.extend(
|
||||
geometry
|
||||
.indices
|
||||
.iter()
|
||||
.filter_map(|&index| geometry.vertices.get(index as usize))
|
||||
.map(|&[x, y]| [x, y, z]),
|
||||
);
|
||||
}
|
||||
|
||||
fn append_custom_wire_points(
|
||||
points: &[[f32; 3]],
|
||||
points_low: &[[f32; 3]],
|
||||
@@ -1928,7 +1973,7 @@ fn fallback_geometry(entity: &EntityType) -> Geometry {
|
||||
|
||||
/// Extract pre-computed edge-wire points from Solid3D / Region / Body entities.
|
||||
///
|
||||
/// AutoCAD stores explicit wire geometry (from SOLVIEW / 3DPLOT) alongside the
|
||||
/// Some drawings store explicit wire geometry alongside the
|
||||
/// ACIS data. We use this as a visible fallback when the SAT tessellator
|
||||
/// produces no mesh (e.g. binary SAB data or unsupported geometry).
|
||||
fn solid_wire_fallback(entity: &EntityType) -> Vec<[f64; 3]> {
|
||||
@@ -2117,7 +2162,7 @@ pub(crate) fn add_polyline(points: &mut Vec<[f32; 3]>, polyline: &[Vec3]) {
|
||||
|
||||
/// Returns the text position of a dimension in DXF world-space (f64, no offset applied).
|
||||
/// Used when building a synthetic Text entity so tessellate() can apply world_offset itself.
|
||||
/// When the saved `text_middle_point` is zero (i.e. AutoCAD never wrote one),
|
||||
/// When the saved `text_middle_point` is zero (no explicit point was written),
|
||||
/// computes a fallback from the dim geometry and applies DIMTAD/DIMGAP.
|
||||
pub(crate) fn normalized_or(v: Vec3, fallback: Vec3) -> Vec3 {
|
||||
if v.length_squared() <= 1e-12 {
|
||||
|
||||
Reference in new issue
Block a user