Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.1.43 #42

Merged
merged 44 commits into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
3c9eec0
Update bevy_panorbit_camera to 0.21.2.
mattatz Dec 24, 2024
9a68d61
Upgrade crates & add trimmed surface example.
mattatz Dec 24, 2024
f712509
Use closest uv coord in try_projection for TrimmedSurface.
mattatz Dec 24, 2024
b199888
Impl Serialize & Deserialize for TrimmedSurface.
mattatz Dec 24, 2024
bf64244
Impl traits for TrimmedSurface.
mattatz Dec 24, 2024
4e3d5e7
Added TrimmedSurface::try_map_closest_point.
mattatz Dec 24, 2024
05191e4
Refactor surface tessellation.
mattatz Dec 24, 2024
d4335b7
Add Constraint for adaptive tesselation node.
mattatz Dec 24, 2024
1c5fb21
Update trimmed_surface.rs
mattatz Dec 25, 2024
07a93e1
Fix a bug to initialize adaptive nodes.
mattatz Dec 25, 2024
bb4e5ac
Refactor AdaptiveTessellationNode::should_divide.
mattatz Dec 25, 2024
3330287
Use UVDirection to divide tessellation nodes.
mattatz Dec 25, 2024
217dd97
WIP.
mattatz Dec 25, 2024
3c70fb2
WIP.
mattatz Dec 25, 2024
5833326
Refactor adaptive tessellation.
mattatz Dec 25, 2024
06079dc
Create NeighborDirection for tessellation.
mattatz Dec 25, 2024
2c8c3ed
WIP.
mattatz Dec 25, 2024
e7a4989
fmt.
mattatz Dec 25, 2024
604378f
Add NurbsSurface::plane.
mattatz Dec 26, 2024
bc8ef59
Remove unused constraints.
mattatz Dec 26, 2024
108a7f0
fmt.
mattatz Dec 26, 2024
fc7f6e6
Invert control points for plane surface.
mattatz Dec 26, 2024
faa5939
Update nurbs_curve.rs
mattatz Dec 26, 2024
433f5ee
Impl accessors for AdaptiveTessellationProcessor.
mattatz Dec 26, 2024
4ea3d1e
Create SurfaceTessellationSeam.
mattatz Dec 31, 2024
e15f223
WIP.
mattatz Dec 31, 2024
a679724
WIP.
mattatz Dec 31, 2024
df9da74
WIP.
mattatz Dec 31, 2024
9cc5ee7
WIP.
mattatz Dec 31, 2024
b30a6a3
Refactor AdaptiveTessellationProcessor.
mattatz Dec 31, 2024
8675ccb
WIP.
mattatz Dec 31, 2024
2d5c442
WIP.
mattatz Jan 2, 2025
6996958
fmt.
mattatz Jan 2, 2025
b54fdd6
WIP.
mattatz Jan 7, 2025
fef6bf8
Refactor.
mattatz Jan 7, 2025
89acfda
Remove unneeded evaluations.
mattatz Jan 7, 2025
c4e3037
WIP.
mattatz Jan 7, 2025
dbe134a
WIP.
mattatz Jan 8, 2025
d75a0f0
Fix typo.
mattatz Jan 8, 2025
4ebeab7
Fix a bug in constrained tessellation.
mattatz Jan 9, 2025
29b29d4
fmt.
mattatz Jan 9, 2025
4d73cee
Remove bevy_inspector_egui.
mattatz Jan 9, 2025
48ad2d6
cargo upgrade.
mattatz Jan 9, 2025
1909e3f
Upgrade to 0.1.43
mattatz Jan 9, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
398 changes: 184 additions & 214 deletions Cargo.lock

Large diffs are not rendered by default.

33 changes: 18 additions & 15 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "curvo"
version = "0.1.42"
version = "0.1.43"
authors = ["Masatatsu Nakamura <masatatsu.nakamura@gmail.com"]
edition = "2021"
keywords = ["nurbs", "modeling", "graphics", "3d"]
Expand All @@ -12,7 +12,7 @@ license = "MIT"
readme = "README.md"

[dependencies]
anyhow = "1.0.94"
anyhow = "1.0.95"
nalgebra = { version = "0.33.2", features = [
"serde-serialize"
] }
Expand All @@ -23,25 +23,24 @@ robust = { version = "1.1.0" }
easer = { version = "0.3.0", optional = true }
simba = { version = "0.9.0", default-features = false }
spade = { version = "2.12.1" }
gauss-quad = "0.2.1"
bevy = { version = "0.15.0", optional = true }
bevy_egui = { version = "0.31.1", optional = true }
bevy-inspector-egui = { version = "0.28.0", optional = true }
gauss-quad = "0.2.2"
bevy = { version = "0.15.1", optional = true }
bevy_egui = { version = "0.32.0", optional = true }
bevy_infinite_grid = { version = "0.14.0", optional = true }
bevy_normal_material = { version = "0.7.1", optional = true }
bevy_panorbit_camera = { version = "0.21.1", optional = true }
bevy_panorbit_camera = { version = "0.21.2", optional = true }
bevy_points = { version = "0.7.0", optional = true }
argmin = "0.10.0"
itertools = "0.13.0"
itertools = "0.14.0"
log = { version = "0.4.22", optional = true }
serde = { version = "1.0.216", optional = true }
serde = { version = "1.0.217", optional = true }

[target.wasm32-unknown-unknown.dependencies]
argmin = { version = "0.10.0", features = ["wasm-bindgen"] }

[dev-dependencies]
approx = { version = "0.5", default-features = false }
serde_json = "1.0.133"
serde_json = "1.0.135"

[features]
default = []
Expand All @@ -51,7 +50,6 @@ bevy = [
"dep:rand_distr",
"dep:bevy",
"dep:bevy_egui",
"dep:bevy-inspector-egui",
"dep:bevy_infinite_grid",
"dep:bevy_normal_material",
"dep:bevy_panorbit_camera",
Expand Down Expand Up @@ -106,10 +104,10 @@ name = "revolve_surface"
path = "examples/revolve_surface.rs"
required-features = ["bevy"]

# [[example]]
# name = "trimmed_surface"
# path = "examples/trimmed_surface.rs"
# required-features = ["bevy"]
[[example]]
name = "trimmed_surface"
path = "examples/trimmed_surface.rs"
required-features = ["bevy"]

[[example]]
name = "frenet_frame"
Expand Down Expand Up @@ -171,3 +169,8 @@ name = "split_surface"
path = "examples/split_surface.rs"
required-features = ["bevy"]

[[example]]
name = "constrained_surface_tessellation"
path = "examples/constrained_surface_tessellation.rs"
required-features = ["bevy"]

2 changes: 0 additions & 2 deletions examples/boolean_curves.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use bevy::{
};
use bevy_infinite_grid::InfiniteGridPlugin;

use bevy_inspector_egui::quick::WorldInspectorPlugin;
use bevy_normal_material::{material::NormalMaterial, plugin::NormalMaterialPlugin};
use bevy_panorbit_camera::{PanOrbitCamera, PanOrbitCameraPlugin};
use bevy_points::{mesh::PointsMesh, plugin::PointsPlugin, prelude::PointsMaterial};
Expand Down Expand Up @@ -37,7 +36,6 @@ fn main() {
.add_plugins(PanOrbitCameraPlugin)
.add_plugins(PointsPlugin)
.add_plugins(NormalMaterialPlugin)
.add_plugins(WorldInspectorPlugin::new())
.add_plugins(AppPlugin)
.run();
}
Expand Down
205 changes: 205 additions & 0 deletions examples/constrained_surface_tessellation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
use std::f64::consts::FRAC_PI_2;

use bevy::{
color::palettes::css::{RED, TOMATO},
prelude::*,
render::{
camera::ScalingMode,
mesh::{Indices, PrimitiveTopology, VertexAttributeValues},
},
};
use bevy_infinite_grid::InfiniteGridPlugin;

use bevy_normal_material::{material::NormalMaterial, plugin::NormalMaterialPlugin};
use bevy_panorbit_camera::{PanOrbitCamera, PanOrbitCameraPlugin};
use bevy_points::{
material::PointsShaderSettings, mesh::PointsMesh, plugin::PointsPlugin, prelude::PointsMaterial,
};
use itertools::Itertools;
use materials::*;
use misc::{add_surface, add_surface_normals};
use nalgebra::{Point3, Rotation3, Translation3, Vector3};

use curvo::prelude::*;
mod materials;
mod misc;

fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(LineMaterialPlugin)
.add_plugins(InfiniteGridPlugin)
.add_plugins(PanOrbitCameraPlugin)
.add_plugins(PointsPlugin)
.add_plugins(NormalMaterialPlugin)
.add_plugins(AppPlugin)
.run();
}
struct AppPlugin;

impl Plugin for AppPlugin {
fn build(&self, app: &mut bevy::prelude::App) {
app.add_systems(Startup, setup);
}
}

fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut line_materials: ResMut<Assets<LineMaterial>>,
mut points_materials: ResMut<Assets<PointsMaterial>>,
mut normal_materials: ResMut<'_, Assets<NormalMaterial>>,
) {
let interpolation_target = vec![
Point3::new(-1.0, -1.0, 0.),
Point3::new(1.0, -1.0, 0.),
Point3::new(1.0, 1.0, 0.),
Point3::new(-1.0, 1.0, 0.),
Point3::new(-1.0, 2.0, 0.),
Point3::new(1.0, 2.5, 0.),
];
let interpolated = NurbsCurve3D::<f64>::try_interpolate(&interpolation_target, 3).unwrap();

let rotation = Rotation3::from_axis_angle(&Vector3::z_axis(), FRAC_PI_2);
let translation = Translation3::new(0., 0., 1.5);
let m = translation * rotation;
let front = interpolated.transformed(&(translation.inverse()).into());
let back = interpolated.transformed(&m.into());

let (umin, umax) = front.knots_domain();

let surface = NurbsSurface::try_loft(&[front, back], Some(3)).unwrap();

let u_parameters = vec![
umin,
(umin + umax) * 0.25,
(umin + umax) * 0.5,
(umin + umax) * 0.75,
umax,
];
let vmin = surface.v_knots_domain().0;

let boundary = BoundaryConstraints::default().with_u_parameters_at_v_min(u_parameters.clone());

commands.spawn((
Mesh3d(
meshes.add(PointsMesh {
vertices: u_parameters
.iter()
.map(|u| surface.point_at(*u, vmin).cast::<f32>().into())
.collect_vec(),
..Default::default()
}),
),
MeshMaterial3d(points_materials.add(PointsMaterial {
settings: PointsShaderSettings {
point_size: 0.05,
color: TOMATO.into(),
..Default::default()
},
circle: true,
..Default::default()
})),
));

// let tess = surface.tessellate(Some(Default::default()));
let option = AdaptiveTessellationOptions {
..Default::default()
};
let tess = surface.constrained_tessellate(boundary, Some(option));
let tess = tess.cast::<f32>();

let vertices = tess.points().iter().map(|pt| (*pt).into()).collect_vec();
commands.spawn((
Mesh3d(meshes.add(PointsMesh {
vertices: vertices.clone(),
..Default::default()
})),
MeshMaterial3d(points_materials.add(PointsMaterial {
settings: PointsShaderSettings {
point_size: 0.02,
color: Color::WHITE.into(),
..Default::default()
},
circle: true,
..Default::default()
})),
));

let normals = tess.normals().iter().map(|n| (*n).into()).collect();
let uvs = tess.uvs().iter().map(|uv| (*uv).into()).collect();
let indices = tess
.faces()
.iter()
.flat_map(|f| f.iter().map(|i| *i as u32))
.collect_vec();

let mesh = Mesh::new(PrimitiveTopology::LineList, default()).with_inserted_attribute(
Mesh::ATTRIBUTE_POSITION,
// triangle edges
VertexAttributeValues::Float32x3(
indices
.chunks(3)
.flat_map(|idx| {
[
vertices[idx[0] as usize].into(),
vertices[idx[1] as usize].into(),
vertices[idx[1] as usize].into(),
vertices[idx[2] as usize].into(),
vertices[idx[2] as usize].into(),
vertices[idx[0] as usize].into(),
]
})
.collect_vec(),
),
);
commands.spawn((
Mesh3d(meshes.add(mesh)),
MeshMaterial3d(line_materials.add(LineMaterial {
color: Color::WHITE.into(),
..Default::default()
})),
));

let mesh = Mesh::new(PrimitiveTopology::TriangleList, default())
.with_inserted_attribute(
Mesh::ATTRIBUTE_POSITION,
VertexAttributeValues::Float32x3(vertices.into_iter().map(|v| v.into()).collect()),
)
.with_inserted_attribute(
Mesh::ATTRIBUTE_NORMAL,
VertexAttributeValues::Float32x3(normals),
)
.with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, VertexAttributeValues::Float32x2(uvs))
.with_inserted_indices(Indices::U32(indices));

commands.spawn((
Mesh3d(meshes.add(mesh)),
MeshMaterial3d(normal_materials.add(NormalMaterial {
cull_mode: None,
..Default::default()
})),
));

let (umin, umax) = surface.u_knots_domain();
let (vmin, vmax) = surface.v_knots_domain();
let center = surface
.point_at((umax + umin) * 0.5, (vmax + vmin) * 0.5)
.cast::<f32>()
.into();

let scale = 5.;
commands.spawn((
Projection::Orthographic(OrthographicProjection {
scale,
near: 1e-1,
far: 1e4,
scaling_mode: ScalingMode::FixedVertical {
viewport_height: 2.,
},
..OrthographicProjection::default_3d()
}),
Transform::from_translation(center + Vec3::new(0., 0., 3.)).looking_at(center, Vec3::Y),
PanOrbitCamera::default(),
));
}
1 change: 0 additions & 1 deletion examples/intersect_curves.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ fn main() {
.add_plugins(PanOrbitCameraPlugin)
.add_plugins(PointsPlugin)
.add_plugins(AppPlugin)
// .add_plugins(WorldInspectorPlugin::new())
.run();
}
struct AppPlugin;
Expand Down
21 changes: 0 additions & 21 deletions examples/misc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,27 +121,6 @@ pub fn add_surface(
let tess = surface.tessellate(Some(option));
let tess = tess.cast::<f32>();

let mut line_list = Mesh::new(bevy::render::mesh::PrimitiveTopology::LineList, default());
let normal_length = 0.15;
let normals = tess.normals();

let vertices = tess
.points()
.iter()
.enumerate()
.flat_map(|(i, p)| {
let pt: Vec3 = (*p).into();
let normal: Vec3 = normals[i].normalize().into();
[pt, pt + normal * normal_length]
})
.map(|p| p.to_array())
.collect();

line_list.insert_attribute(
Mesh::ATTRIBUTE_POSITION,
VertexAttributeValues::Float32x3(vertices),
);

let vertices = tess.points().iter().map(|pt| (*pt).into()).collect();
let normals = tess.normals().iter().map(|n| (*n).into()).collect();
let uvs = tess.uvs().iter().map(|uv| (*uv).into()).collect();
Expand Down
Loading
Loading