Simplify signature or Operation::triangles

This is less performance-friendly, due to the additional allocations
that might be required. But for now, it's easier to work with, I think.
I can revisit the performance implications later again, when my thinking
around this whole API has solidified a bit more.
This commit is contained in:
Hanno Braun 2025-01-15 20:40:29 +01:00
parent b3f9745f56
commit 79d19fbc49
9 changed files with 37 additions and 22 deletions

View File

@ -1,10 +1,9 @@
use std::{collections::BTreeMap, fs::File};
use crate::geometry::{Operation, Shape, TriMesh};
use crate::geometry::{Operation, Shape};
pub fn export(shape: &Shape) -> anyhow::Result<()> {
let mut tri_mesh = TriMesh::new();
shape.triangles(&mut tri_mesh);
let tri_mesh = shape.triangles();
let mut indices_by_vertex = BTreeMap::new();

View File

@ -3,7 +3,7 @@ use std::{fmt, ops::Deref, rc::Rc};
use super::tri_mesh::TriMesh;
pub trait Operation: fmt::Display {
fn triangles(&self, mesh: &mut TriMesh);
fn triangles(&self) -> TriMesh;
fn children(&self) -> Vec<AnyOp>;
}
@ -68,8 +68,8 @@ impl fmt::Display for AnyOp {
}
impl Operation for AnyOp {
fn triangles(&self, mesh: &mut TriMesh) {
self.inner.triangles(mesh);
fn triangles(&self) -> TriMesh {
self.inner.triangles()
}
fn children(&self) -> Vec<AnyOp> {

View File

@ -31,9 +31,11 @@ impl fmt::Display for Shape {
}
impl Operation for Shape {
fn triangles(&self, mesh: &mut TriMesh) {
fn triangles(&self) -> TriMesh {
if let Some(op) = self.sequence.last() {
op.triangles(mesh);
op.triangles()
} else {
TriMesh::new()
}
}
@ -52,11 +54,14 @@ struct OperationInSequence {
}
impl Operation for OperationInSequence {
fn triangles(&self, mesh: &mut TriMesh) {
if let Some(op) = &self.previous {
op.triangles(mesh);
}
self.operation.triangles(mesh);
fn triangles(&self) -> TriMesh {
let mesh = if let Some(op) = &self.previous {
op.triangles()
} else {
TriMesh::new()
};
mesh.merge(self.operation.triangles())
}
fn children(&self) -> Vec<AnyOp> {

View File

@ -10,4 +10,9 @@ impl TriMesh {
triangles: Vec::new(),
}
}
pub fn merge(mut self, other: Self) -> Self {
self.triangles.extend(other.triangles);
self
}
}

View File

@ -27,8 +27,10 @@ impl fmt::Display for Triangle {
}
impl Operation for Triangle {
fn triangles(&self, mesh: &mut TriMesh) {
mesh.triangles.push(self.clone())
fn triangles(&self) -> TriMesh {
TriMesh {
triangles: vec![self.clone()],
}
}
fn children(&self) -> Vec<AnyOp> {

View File

@ -1,7 +1,7 @@
use glam::Vec3;
use wgpu::util::DeviceExt;
use crate::geometry::{Operation, TriMesh};
use crate::geometry::Operation;
use super::vertex::Vertex;
@ -13,8 +13,7 @@ pub struct Geometry {
impl Geometry {
pub fn new(device: &wgpu::Device, operation: &dyn Operation) -> Self {
let mut tri_mesh = TriMesh::new();
operation.triangles(&mut tri_mesh);
let tri_mesh = operation.triangles();
let mut indices = Vec::new();
let mut vertices = Vec::new();

View File

@ -43,7 +43,7 @@ impl fmt::Display for Face {
}
impl Operation for Face {
fn triangles(&self, mesh: &mut TriMesh) {
fn triangles(&self) -> TriMesh {
// This is a placeholder implementation that only supports convex faces.
let mut triangulation =
@ -81,6 +81,7 @@ impl Operation for Face {
)
.unwrap();
let mut mesh = TriMesh::new();
mesh.triangles
.extend(triangulation.inner_faces().map(|triangle| {
let points = triangle
@ -88,6 +89,8 @@ impl Operation for Face {
.map(|vertex| vertex.data().point_vertex);
Triangle { points }
}));
mesh
}
fn children(&self) -> Vec<AnyOp> {

View File

@ -29,7 +29,9 @@ impl fmt::Display for Vertex {
}
impl Operation for Vertex {
fn triangles(&self, _: &mut TriMesh) {}
fn triangles(&self) -> TriMesh {
TriMesh::new()
}
fn children(&self) -> Vec<AnyOp> {
Vec::new()

View File

@ -128,8 +128,8 @@ impl fmt::Display for OperationView {
}
impl Operation for OperationView {
fn triangles(&self, mesh: &mut TriMesh) {
self.operation.triangles(mesh);
fn triangles(&self) -> TriMesh {
self.operation.triangles()
}
fn children(&self) -> Vec<AnyOp> {