feat: Solid3D wire fallback render + Ole2Frame placeholder
- When SAT tessellation yields no mesh (binary SAB or unsupported ACIS geometry), render the pre-computed edge-wire polylines stored in Solid3D / Region / Body entities as a visible line fallback. - Ole2Frame entities now render a bounding rectangle with diagonal X instead of an invisible stub — marks embedded OLE objects in the viewport. Closes ROADMAP 2.13 (partial), 3.2 (Ole2Frame). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
5cf7a19ca8
commit
28f5c84b09
1 changed files with 65 additions and 2 deletions
|
|
@ -181,8 +181,12 @@ pub fn tessellate(
|
|||
}
|
||||
|
||||
TruckObject::Volume(_) => {
|
||||
// Solid3D → handled by tessellate_mesh(), not WireModel.
|
||||
return WireModel::solid(name, vec![], color, selected);
|
||||
// Solid3D / Region / Body → handled by tessellate_mesh().
|
||||
// As a wire fallback, render the pre-computed edge wires
|
||||
// stored in the entity when present (e.g. from SOLVIEW output
|
||||
// or when the SAT kernel cannot parse the ACIS data).
|
||||
let wire_pts = solid_wire_fallback(entity);
|
||||
return WireModel::solid(name, wire_pts, color, selected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -561,6 +565,30 @@ fn legacy_geometry(entity: &EntityType) -> Geometry {
|
|||
}
|
||||
(pts, vec![], vec![], vec![])
|
||||
}
|
||||
EntityType::Ole2Frame(ole) => {
|
||||
// OLE objects carry a bounding rectangle in model space.
|
||||
// Render a simple X-through-rectangle placeholder.
|
||||
let x0 = ole.upper_left_corner.x as f32;
|
||||
let y0 = ole.lower_right_corner.y as f32;
|
||||
let x1 = ole.lower_right_corner.x as f32;
|
||||
let y1 = ole.upper_left_corner.y as f32;
|
||||
let z = ole.upper_left_corner.z as f32;
|
||||
if (x1 - x0).abs() < 1e-6 && (y1 - y0).abs() < 1e-6 {
|
||||
// Degenerate / unknown size — show a small cross.
|
||||
let s = 0.5_f32;
|
||||
return (vec![[-s, 0.0, 0.0], [s, 0.0, 0.0]], vec![], vec![], vec![]);
|
||||
}
|
||||
let pts = vec![
|
||||
// Outer rectangle
|
||||
[x0, y0, z], [x1, y0, z], [x1, y0, z], [x1, y1, z],
|
||||
[x1, y1, z], [x0, y1, z], [x0, y1, z], [x0, y0, z],
|
||||
// Diagonal X
|
||||
[x0, y0, z], [x1, y1, z],
|
||||
[f32::NAN, f32::NAN, f32::NAN],
|
||||
[x1, y0, z], [x0, y1, z],
|
||||
];
|
||||
(pts, vec![], vec![], vec![[x0, y0, z], [x1, y1, z]])
|
||||
}
|
||||
_ => {
|
||||
let s = 0.5_f32;
|
||||
(vec![[-s, 0.0, 0.0], [s, 0.0, 0.0]], vec![], vec![], vec![])
|
||||
|
|
@ -568,6 +596,41 @@ fn legacy_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
|
||||
/// 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<[f32; 3]> {
|
||||
let wires: &[acadrust::entities::Wire] = match entity {
|
||||
EntityType::Solid3D(s) => &s.wires,
|
||||
EntityType::Region(r) => &r.wires,
|
||||
EntityType::Body(b) => &b.wires,
|
||||
_ => return vec![],
|
||||
};
|
||||
|
||||
if wires.is_empty() {
|
||||
return vec![];
|
||||
}
|
||||
|
||||
let mut pts: Vec<[f32; 3]> = Vec::new();
|
||||
for wire in wires {
|
||||
if wire.points.len() < 2 {
|
||||
continue;
|
||||
}
|
||||
for (i, v) in wire.points.iter().enumerate() {
|
||||
if i > 0 {
|
||||
// Connect segments: repeat previous point then add current so
|
||||
// the wire renderer draws a continuous polyline per wire.
|
||||
}
|
||||
pts.push([v.x as f32, v.y as f32, v.z as f32]);
|
||||
}
|
||||
// NaN sentinel separates distinct wire segments.
|
||||
pts.push([f32::NAN, f32::NAN, f32::NAN]);
|
||||
}
|
||||
pts
|
||||
}
|
||||
|
||||
fn dimension_geometry(dim: &Dimension) -> Vec<[f32; 3]> {
|
||||
let mut points = Vec::new();
|
||||
match dim {
|
||||
|
|
|
|||
Loading…
Reference in a new issue