Skip to content

Commit

Permalink
Improve zslice algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
lbirkert committed Aug 3, 2023
1 parent 874829c commit 80eafc6
Show file tree
Hide file tree
Showing 17 changed files with 41 additions and 60 deletions.
2 changes: 1 addition & 1 deletion src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::task::Poll;
use std::{future::Future, io::Cursor};

use crate::{
core::primitives::Mesh,
core::Mesh,
editor::{object::Object, Editor},
view::{prepare::PrepareView, View},
};
Expand Down
File renamed without changes.
50 changes: 16 additions & 34 deletions src/core/primitives/mesh.rs → src/core/mesh.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{collections::HashSet, io::Cursor};
use std::io::Cursor;

use nalgebra::{Matrix4, UnitVector3, Vector2, Vector3};

Expand Down Expand Up @@ -49,28 +49,28 @@ impl Mesh {
Self::z_slice_raw(&self.triangles, z)
}

/// TODO: Rewrite
/// Z-Slice a model. Creates a path representing the outline of this Mesh at this z height.
pub fn z_slice_raw(triangles: &[Triangle], z: f32) -> Vec<Path2> {
// Used for connecting the polygons properly
let mut points: Vec<Vector2<f32>> = Vec::new();
let mut segments: HashSet<(usize, usize)> = HashSet::new();
let mut indicies: Vec<(usize, bool)> = Vec::new();
let mut indicies: Vec<Vec<usize>> = Vec::new();

for triangle in triangles.iter() {
let a = triangle.a;
let b = triangle.b;
let c = triangle.c;
let pa = if (a.z > z) != (b.z > z) {
let pa = if a.z.min(b.z) < z && a.z.max(b.z) > z {
Some(a.xy().lerp(&b.xy(), 1.0 - (z - b.z) / (a.z - b.z)))
} else {
None
};
let pb = if (b.z > z) != (c.z > z) {
let pb = if b.z.min(c.z) < z && b.z.max(c.z) > z {
Some(b.xy().lerp(&c.xy(), 1.0 - (z - c.z) / (b.z - c.z)))
} else {
None
};
let pc = if (c.z > z) != (a.z > z) {
let pc = if c.z.min(a.z) < z && c.z.max(a.z) > z {
Some(c.xy().lerp(&a.xy(), 1.0 - (z - a.z) / (c.z - a.z)))
} else {
None
Expand All @@ -85,22 +85,12 @@ impl Mesh {

const EPSILON: f32 = 1e-9;

// Skip 'zero' length segments
if (segment.0 - segment.1).magnitude_squared() < EPSILON {
continue;
}

let a: Vector2<f32>;
let b: Vector2<f32>;

let delta = Vector3::z_axis().cross(&triangle.normal).xy();
if (segment.1 - segment.0).dot(&delta) > 0.0 {
a = segment.0;
b = segment.1;
let (a, b) = if (segment.1 - segment.0).dot(&delta) > 0.0 {
(segment.0, segment.1)
} else {
b = segment.0;
a = segment.1;
}
(segment.1, segment.0)
};

let mut ai = None;
for (i, point) in points.iter().enumerate() {
Expand All @@ -112,7 +102,7 @@ impl Mesh {

let ai = ai.unwrap_or_else(|| {
points.push(a);
indicies.push((0, false));
indicies.push(Vec::new());
points.len() - 1
});

Expand All @@ -126,18 +116,11 @@ impl Mesh {

let bi = bi.unwrap_or_else(|| {
points.push(b);
indicies.push((0, false));
indicies.push(Vec::new());
points.len() - 1
});

// Check for zero area path
if !segments.remove(&(bi, ai)) {
segments.insert((ai, bi));
}
}

for segment in segments {
indicies[segment.0].0 = segment.1;
indicies[ai].push(bi);
}

if indicies.is_empty() {
Expand All @@ -149,12 +132,12 @@ impl Mesh {

let mut pointer = 0;
loop {
if indicies[pointer].1 {
if indicies[pointer].is_empty() {
paths.push(Path2::new(path));

let mut found = None;
for (i, index) in indicies.iter().enumerate() {
if !index.1 {
if !index.is_empty() {
found = Some(i);
break;
}
Expand All @@ -168,8 +151,7 @@ impl Mesh {
}
} else {
path.push(points[pointer]);
indicies[pointer].1 = true;
pointer = indicies[pointer].0;
pointer = indicies[pointer].pop().unwrap();
}
}

Expand Down
19 changes: 18 additions & 1 deletion src/core/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,18 @@
pub mod primitives;
pub mod axis;
pub mod mesh;
pub mod path;
pub mod plane;
pub mod ray;
pub mod sphere;
pub mod square;
pub mod triangle;

pub use axis::Axis;
pub use mesh::Mesh;
pub use path::Path2;
pub use path::Path3;
pub use plane::Plane;
pub use ray::Ray;
pub use sphere::Sphere;
pub use square::Square;
pub use triangle::Triangle;
File renamed without changes.
File renamed without changes.
18 changes: 0 additions & 18 deletions src/core/primitives/mod.rs

This file was deleted.

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion src/editor/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use eframe::wgpu;

use eframe::wgpu::util::DeviceExt;

use crate::core::primitives::Ray;
use crate::core::Ray;

#[repr(C)]
#[derive(Clone, Copy, bytemuck::Zeroable, bytemuck::Pod)]
Expand Down
2 changes: 1 addition & 1 deletion src/editor/log.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::collections::HashSet;

use crate::core::primitives::Mesh;
use crate::core::Mesh;

use super::{object::Object, tool::Tool};

Expand Down
2 changes: 1 addition & 1 deletion src/editor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use egui::{ScrollArea, Vec2};
use nalgebra::{UnitVector3, Vector3};
use std::sync::Arc;

use crate::{core::primitives::Plane, renderer};
use crate::{core::Plane, renderer};

pub mod camera;
pub mod icons;
Expand Down
2 changes: 1 addition & 1 deletion src/editor/object.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::core::primitives::Mesh;
use crate::core::Mesh;
use egui::vec2;

use super::{icons::Icons, log::Message, state::State};
Expand Down
2 changes: 1 addition & 1 deletion src/editor/tool.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use nalgebra::{UnitVector3, Vector3};

use crate::{
core::primitives::{Axis, Mesh, Ray, Square},
core::{Axis, Mesh, Ray, Square},
renderer,
};

Expand Down
2 changes: 1 addition & 1 deletion src/renderer/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::sync::Arc;

use eframe::wgpu;

use crate::core::primitives::Triangle;
use crate::core::Triangle;

pub const VERTEX_SIZE: usize = std::mem::size_of::<Vertex>();
pub const VERTEX_BUFFER_LAYOUT: wgpu::VertexBufferLayout<'static> = wgpu::VertexBufferLayout {
Expand Down

0 comments on commit 80eafc6

Please sign in to comment.