Fix revolve angle and wireframe display

This commit is contained in:
ramox81 committed 2026-09-03 16:24:43 +03:00
1 parent 5bbb0bbe1f
commit 1a913ee640
8 files changed
+138 -26

No files matched your search

+21 -4
View File
@@ -2723,14 +2723,28 @@ impl Scene {
}
/// Cache and display a Model-tab kernel solid.
pub fn register_solid_model(&mut self, handle: Handle, solid: cadkernel::brep::Body) {
pub fn register_solid_model(
&mut self,
handle: Handle,
solid: cadkernel::brep::Body,
) -> bool {
let color = self
.document
.get_entity(handle)
.map(|e| self.render_style(e).0)
.unwrap_or([0.8, 0.8, 0.85, 1.0]);
if let Some((mut set, wires, center)) =
crate::scene::model::solid_model::display_from_solid(&solid, color)
let facet_resolution = self.document.header.facet_resolution;
let chordal_deflection =
crate::entities::solid3d::display_deflection(&self.document.header, facet_resolution);
let isolines = self.document.header.isolines.max(0) as usize;
let displayed = if let Some((mut set, wires, center)) =
crate::scene::model::solid_model::display_from_solid(
&solid,
color,
facet_resolution,
chordal_deflection,
isolines,
)
{
if let Some(entity) = self.document.get_entity_mut(handle) {
let reference = acadrust::types::Vector3::new(center[0], center[1], center[2]);
@@ -2772,15 +2786,18 @@ impl Scene {
);
}
self.meshes.insert(handle, set);
true
} else {
self.meshes.remove(&handle);
}
false
};
self.solid_models.insert(handle, solid);
self.sync_solid_reference_point(handle);
// Only this solid's mesh changed — report just its handle so the mesh /
// wire caches patch it in rather than rebuilding the whole drawing (and
// so a bulk register loop stays O(n), not O(n²)).
self.bump_entities(&[(handle, ChangeKind::Modified)]);
displayed
}
/// `BACKGROUND` change picks up the new `adapt_to_bg` result without
+40 -4
View File
@@ -18,6 +18,29 @@ fn tessellation(body: &Body) -> brep::mesh::BodyMesh {
)
}
fn display_tessellation(
body: &Body,
facet_resolution: f64,
chordal_deflection: Option<f64>,
isolines: usize,
) -> brep::mesh::BodyMesh {
let resolution = if facet_resolution.is_finite() && facet_resolution > 0.0 {
facet_resolution.clamp(0.01, 10.0)
} else {
1.0
};
let max_angle = chordal_deflection.map_or_else(
|| cadkernel::tessellation::angle_for_resolution(resolution),
|_| cadkernel::tessellation::display_angle_for_resolution(resolution),
);
let mut tolerance = brep::mesh::TessellationTolerance::new(max_angle, TOL)
.with_isolines(isolines);
if let Some(deflection) = chordal_deflection {
tolerance = tolerance.with_chordal_deflection(deflection);
}
brep::mesh::tessellate(body, tolerance)
}
/// Axis-aligned box from its center and full extents.
pub fn box_solid(center: [f64; 3], length: f64, width: f64, height: f64) -> Option<Body> {
brep::make::cuboid(
@@ -397,8 +420,13 @@ fn mesh_from_tessellation(
color,
selected: false,
});
for edge in tessellation.edges {
for segment in edge.positions.windows(2) {
for positions in tessellation
.edges
.into_iter()
.map(|edge| edge.positions)
.chain(tessellation.isolines.into_iter().map(|line| line.positions))
{
for segment in positions.windows(2) {
for point in segment {
let high = [point[0] as f32, point[1] as f32, point[2] as f32];
set.edge_verts.push(high);
@@ -418,9 +446,17 @@ fn mesh_from_tessellation(
pub fn display_from_solid(
body: &Body,
color: [f32; 4],
facet_resolution: f64,
chordal_deflection: Option<f64>,
isolines: usize,
) -> Option<(MeshLodSet, Vec<acadrust::entities::Wire>, [f64; 3])> {
use acadrust::types::Vector3;
let tessellation = tessellation(body);
let tessellation = display_tessellation(
body,
facet_resolution,
chordal_deflection,
isolines,
);
let center = mesh_center(&tessellation.mesh)?;
let wires = tessellation
.edges
@@ -496,7 +532,7 @@ mod tests {
use super::*;
fn tri_count(body: &Body) -> usize {
display_from_solid(body, [0.7, 0.7, 0.7, 1.0])
display_from_solid(body, [0.7, 0.7, 0.7, 1.0], 1.0, None, 0)
.map(|(m, _, _)| m.lods[0].indices.len() / 3)
.unwrap_or(0)
}
+13 -1
View File
@@ -781,7 +781,19 @@ impl Scene {
// ── Erase ─────────────────────────────────────────────────────────────
pub fn erase_entities(&mut self, handles: &[Handle]) {
self.remove_entities(handles, true);
}
/// Roll back entities created by the current command after a downstream
/// registration failure. These entities were never successful command
/// results, so locked-layer edit policy must not prevent their removal.
/// The shared removal path keeps first-touch undo state, history objects,
/// groups, selection, and derived caches coherent.
pub(crate) fn rollback_new_entities(&mut self, handles: &[Handle]) {
self.remove_entities(handles, false);
}
fn remove_entities(&mut self, handles: &[Handle], respect_layer_locks: bool) {
let erase_handles = self.handles_expanded_for_leader_annotations(handles);
let mut handle_set: HashSet<Handle> = HashSet::default();
@@ -791,7 +803,7 @@ impl Scene {
for &h in &erase_handles {
// Objects on a locked layer can't be erased.
if self.is_layer_locked(h) {
if respect_layer_locks && self.is_layer_locked(h) {
continue;
}
// Delta-undo: capture the removed entity so an undo can re-insert it.