Skip to content

Commit

Permalink
star helix
Browse files Browse the repository at this point in the history
  • Loading branch information
Agapanthus committed Mar 5, 2024
1 parent e9e91da commit 981c7c1
Show file tree
Hide file tree
Showing 10 changed files with 199 additions and 37 deletions.
46 changes: 37 additions & 9 deletions editor/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,12 @@ struct MeshSettings {
#[inspector(min = 0.0, max = 10.0)]
r: f32,

#[inspector(min = 0.0, max = 10.0)]
r2: f32,

d1: Vec3,
d2: Vec3,
d3: Vec3,
rot: f32,
segs: usize,
}

impl Default for MeshSettings {
Expand All @@ -56,26 +59,51 @@ impl Default for MeshSettings {
tol: -4.0,
n: 30,
r: 1.0,
d1: Vec3::new(0.4, -1.0, 0.0),
d2: Vec3::new(0.2, 0.3, 0.2),
d3: Vec3::new(0.2, -0.3, 0.2),
r2: 0.8,
d1: Vec3::new(0.4, 0.3, 0.0),
rot: 0.3,
segs: 30,
}
}
}

fn make_mesh(settings: &MeshSettings) -> MeshVec3 {
let mut mesh = MeshVec3::regular_polygon(settings.r, settings.n); //cuboid(1.0, 1.0, 2.0);
mesh.extrude(mesh.edge_between(1, 0).unwrap().id(), settings.d1, true);
let mut mesh = MeshVec3::regular_star(settings.r, settings.r2, settings.n); //cuboid(1.0, 1.0, 2.0);

mesh.transform(
&bevy::transform::components::Transform::from_translation(Vec3::new(0.0, -1.0, 0.0))
.with_rotation(Quat::from_rotation_z(PI)),
);

let mut f = mesh.extrude_ex(
mesh.edge_between(1, 0).unwrap().id(),
bevy::transform::components::Transform::from_rotation(Quat::from_rotation_y(settings.rot))
.with_translation(settings.d1),
true,
);

for _ in 0..settings.segs {
f = mesh.extrude_face_ex(
f,
bevy::transform::components::Transform::from_rotation(Quat::from_rotation_y(
settings.rot,
))
.with_translation(settings.d1),
true,
);
}

/* mesh.extrude(mesh.edge_between(1, 0).unwrap().id(), settings.d1, true);
let fe = mesh.extrude_face(1, settings.d2, true);
mesh.extrude_face(fe, settings.d3, true);
mesh.extrude_face(fe, settings.d3, true);*/

println!("{}", mesh);
mesh
}

pub fn main() {
env::set_var("RUST_BACKTRACE", "1"); // or "full"


App::new()
.add_plugins(DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window {
Expand Down
5 changes: 5 additions & 0 deletions src/representation/deletable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ impl<T: Deletable<I> + Default, I: IndexType> DeletableVector<T, I> {
pub fn iter(&self) -> impl Iterator<Item = &T> {
self.data.iter().filter(|f| !f.is_deleted())
}

/// Returns a mutable iterator over the non-deleted elements.
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
self.data.iter_mut().filter(|f| !f.is_deleted())
}

/// Returns the requested element. Panics if it doesn't exist or is deleted.
pub fn get(&self, index: I) -> &T {
Expand Down
8 changes: 5 additions & 3 deletions src/representation/face/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::representation::payload::{Transform3D, Vector3D};
use crate::representation::payload::{Transform, Vector3D};

use super::{
payload::{Payload, Scalar, Vector},
Expand Down Expand Up @@ -82,6 +82,9 @@ impl<E: IndexType, F: IndexType> Face<E, F> {
return true;
}

// TODO: Ignoring planar-ness for now
return true;

// TODO: is this correct?
// TODO: collinear points cause problems

Expand Down Expand Up @@ -163,11 +166,10 @@ impl<E: IndexType, F: IndexType> Face<E, F> {

let normal = self.normal(mesh);
let z_axis = P::Vec::from_xyz(0.0.into(), 0.0.into(), 1.0.into());
let rotation = <P::Vec as Vector3D<P::S>>::Transform::from_rotation_arc(
let rotation = <P::Vec as Vector<P::S>>::Transform::from_rotation_arc(
normal.normalize(),
z_axis.normalize(),
);
let mut vs: Vec<_> = self.vertices(mesh).map(|v| *v.vertex()).collect();
self.vertices(mesh)
.map(move |v| (rotation.apply(*v.vertex()).xy(), v.id()))
}
Expand Down
33 changes: 30 additions & 3 deletions src/representation/mesh/builder/extrude.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::representation::{
builder::{AddVertex, CloseFace},
payload::Payload,
payload::{Payload, Transform, Vector},
IndexType, Mesh,
};

Expand All @@ -13,15 +13,30 @@ where
{
/// Extrudes the given edge in the given direction.
/// Returns the closing face if it was created.
pub fn extrude(&mut self, e: E, direction: P::Vec, close: bool) -> F{
pub fn extrude(&mut self, e: E, direction: P::Vec, close: bool) -> F {
self.extrude_ex(
e,
<P::Vec as Vector<P::S>>::Transform::from_translation(direction),
close,
)
}

/// Extrudes the given edge using the given transformation.
/// Returns the closing face if it was created.
pub fn extrude_ex(
&mut self,
e: E,
transform: <P::Vec as Vector<P::S>>::Transform,
close: bool,
) -> F {
assert!(self.edge(e).is_boundary_self());

let first = self.edge(e).origin_id();
let mut last = first;
let mut second = first;
let edges = self.edge(e).edges_face_back(self).collect::<Vec<_>>();
for i in 0..edges.len() {
let p = edges[i].origin(self).payload().translate(&direction);
let p = edges[i].origin(self).payload().transform(&transform);

let curr = self.add_vertex((last, p)).0;
if i > 0 {
Expand All @@ -48,4 +63,16 @@ where
self.remove_face(f);
return self.extrude(e, direction, close);
}

/// Extrudes the given face in the given direction.
pub fn extrude_face_ex(
&mut self,
f: F,
transform: <P::Vec as Vector<P::S>>::Transform,
close: bool,
) -> F {
let e = self.face(f).edge_id();
self.remove_face(f);
return self.extrude_ex(e, transform, close);
}
}
9 changes: 8 additions & 1 deletion src/representation/mesh/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ where
pub fn num_vertices(&self) -> usize {
self.vertices.len()
}

/// Returns the maximum vertex index in the mesh
pub fn max_vertex_index(&self) -> usize {
self.vertices.max_ind()
Expand Down Expand Up @@ -148,4 +148,11 @@ where
pub fn faces(&self) -> impl Iterator<Item = &Face<E, F>> {
self.faces.iter()
}

/// Transforms all vertices in the mesh
pub fn transform(&mut self, t: &<P::Vec as super::payload::Vector<P::S>>::Transform) {
for v in self.vertices.iter_mut() {
v.transform(t);
}
}
}
19 changes: 14 additions & 5 deletions src/representation/mesh/primitives/regular_polygon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,36 @@ where
{
/// create a regular polygon
pub fn regular_polygon(radius: P::S, n: usize) -> Mesh<E, V, F, P> {
Self::regular_star(radius, radius, n)
}

/// create a regular polygon
pub fn regular_star(inner_radius: P::S, outer_radius: P::S, n: usize) -> Mesh<E, V, F, P> {
let pi2n = 2.0 * std::f32::consts::PI / (n as f32);
let a0 = 0.0 as f32;
let a1 = pi2n;
let mut mesh = Mesh::<E, V, F, P>::new();

let (v0, mut current) = mesh.add_isolated_edge(
P::from_vec(P::Vec::from_xyz(
radius * P::S::from(a0.sin()),
inner_radius * P::S::from(a0.sin()),
P::S::default(),
radius * P::S::from(a0.cos()),
inner_radius * P::S::from(a0.cos()),
)),
P::from_vec(P::Vec::from_xyz(
radius * P::S::from(a1.sin()),
inner_radius * P::S::from(a1.sin()),
P::S::default(),
radius * P::S::from(a1.cos()),
inner_radius * P::S::from(a1.cos()),
)),
);
let mut prev = v0;

for i in 2..n {
let r = if i % 2 == 0 { radius } else { radius * 0.8.into() };
let r = if i % 2 == 0 {
outer_radius
} else {
inner_radius
};
let angle = pi2n * (i as f32);
prev = current;
current = mesh
Expand Down
8 changes: 8 additions & 0 deletions src/representation/vertex/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use self::payload::Vector;

use super::{Deletable, HalfEdge, IndexType, Mesh};
use payload::Payload;
mod iterator;
Expand Down Expand Up @@ -88,6 +90,12 @@ impl<E: IndexType, V: IndexType, P: Payload> Vertex<E, V, P> {
let e = self.edge(mesh);
e.prev_id() == e.twin_id()
}

/// Transforms the payload.
#[inline(always)]
pub fn transform(&mut self, transform: &<P::Vec as Vector<P::S>>::Transform) {
self.payload = self.payload.transform(transform);
}
}

impl<E: IndexType, V: IndexType, P: Payload> std::fmt::Display for Vertex<E, V, P> {
Expand Down
84 changes: 73 additions & 11 deletions src/representation/vertex/payload/bevy.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
//! Bevy specific implementations for the vertex payload and 3d rotation.

use super::{Payload, Transform3D, Vector, Vector2D, Vector3D};
use bevy::{
math::{Quat, Vec2, Vec3},
transform::components::Transform,
};
use super::{Payload, Transform, Vector, Vector2D, Vector3D};
use bevy::math::{Affine2, Quat, Vec2, Vec3};

impl Vector<f32> for Vec3 {
type Vec2D = Vec2;
type Vec3D = Vec3;
type Transform = bevy::transform::components::Transform;

#[inline(always)]
fn zero() -> Self {
Expand Down Expand Up @@ -67,8 +65,6 @@ impl Vector<f32> for Vec3 {
}

impl Vector3D<f32> for Vec3 {
type Transform = Transform;

#[inline(always)]
fn from_xyz(x: f32, y: f32, z: f32) -> Self {
Vec3::new(x, y, z)
Expand All @@ -78,6 +74,7 @@ impl Vector3D<f32> for Vec3 {
impl Vector<f32> for Vec2 {
type Vec2D = Vec2;
type Vec3D = Vec3;
type Transform = Affine2;

#[inline(always)]
fn zero() -> Self {
Expand Down Expand Up @@ -163,6 +160,15 @@ impl Payload for BevyPayload {
}
}

#[inline(always)]
fn transform(&self, t: &<Self::Vec as Vector<Self::S>>::Transform) -> Self {
Self {
position: t.apply(self.position),
normal: t.apply_vec(self.normal),
uv: self.uv,
}
}

#[inline(always)]
fn vertex(&self) -> &Self::Vec {
&self.position
Expand All @@ -178,25 +184,36 @@ impl Payload for BevyPayload {
}
}

impl Transform3D for Transform {
// TODO: Switch to Affine3
impl Transform for bevy::transform::components::Transform {
type S = f32;
type Vec = Vec3;

#[inline(always)]
fn identity() -> Self {
Transform::default()
bevy::transform::components::Transform::default()
}

#[inline(always)]
fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
Transform::from_rotation(Quat::from_axis_angle(axis, angle))
bevy::transform::components::Transform::from_rotation(Quat::from_axis_angle(axis, angle))
}

#[inline(always)]
fn from_rotation_arc(from: Vec3, to: Vec3) -> Self {
assert!((from.length() - 1.0).abs() < 0.01);
assert!((to.length() - 1.0).abs() < 0.01);
Transform::from_rotation(Quat::from_rotation_arc(from, to))
bevy::transform::components::Transform::from_rotation(Quat::from_rotation_arc(from, to))
}

#[inline(always)]
fn from_translation(v: Vec3) -> Self {
bevy::transform::components::Transform::from_translation(v)
}

#[inline(always)]
fn from_scale(v: Vec3) -> Self {
bevy::transform::components::Transform::from_scale(v)
}

#[inline(always)]
Expand All @@ -210,4 +227,49 @@ impl Transform3D for Transform {
}
v2
}

#[inline(always)]
fn apply_vec(&self, v: Vec3) -> Vec3 {
self.apply(v)
}
}

impl Transform for Affine2 {
type S = f32;
type Vec = Vec2;

#[inline(always)]
fn identity() -> Self {
Affine2::IDENTITY
}

#[inline(always)]
fn from_axis_angle(axis: Vec2, angle: f32) -> Self {
bevy::math::Affine2::from_axis_angle(axis, angle)
}

#[inline(always)]
fn from_rotation_arc(from: Vec2, to: Vec2) -> Self {
bevy::math::Affine2::from_rotation_arc(from, to)
}

#[inline(always)]
fn from_translation(v: Vec2) -> Self {
bevy::math::Affine2::from_translation(v)
}

#[inline(always)]
fn from_scale(v: Vec2) -> Self {
bevy::math::Affine2::from_scale(v)
}

#[inline(always)]
fn apply(&self, v: Vec2) -> Vec2 {
bevy::math::Affine2::transform_point2(self, v)
}

#[inline(always)]
fn apply_vec(&self, v: Vec2) -> Vec2 {
bevy::math::Affine2::transform_vector2(self, v)
}
}

0 comments on commit 981c7c1

Please sign in to comment.