update dependencies

This commit is contained in:
Alex Mikhalev 2023-05-01 17:57:17 -07:00
parent fdd93fa7e8
commit fc550267da
4 changed files with 1823 additions and 1017 deletions

2564
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -6,16 +6,16 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
argmin = { version = "0.5.1", features = ["nalgebra"] }
bevy_ecs = "0.7.0"
eframe = { version = "0.18.0", features = [] }
argmin = { version = "0.8.1", features = [] }
argmin-math = { version = "0.3.0", features = ["nalgebra_0_32"] }
bevy_ecs = "0.10.1"
eframe = { version = "0.21.3", features = [] }
indexmap = "1.8.1"
iyes_loopless = "0.5.1"
levenberg-marquardt = "0.12.0"
nalgebra = "0.30.1"
nalgebra-sparse = "0.6.0"
levenberg-marquardt = "0.13.0"
nalgebra = "0.32.0"
nalgebra-sparse = "0.9.0"
nohash-hasher = "0.2.0"
[dev-dependencies]
criterion = "0.3.5"
criterion = "0.4.0"

View File

@ -62,9 +62,9 @@ pub struct Circle {
pub fn insert_point_at(commands: &mut Commands, point: impl Into<PointPos>) -> PointId {
let point = point.into();
let x = commands.spawn().insert(Var::new_free(point.x)).id();
let y = commands.spawn().insert(Var::new_free(point.y)).id();
commands.spawn().insert(Point::new(x, y)).id()
let x = commands.spawn(Var::new_free(point.x)).id();
let y = commands.spawn(Var::new_free(point.y)).id();
commands.spawn(Point::new(x, y)).id()
}
// TODO: figure out generic for this

View File

@ -1,14 +1,15 @@
use std::ops::{Deref, DerefMut};
use bevy_ecs::{
prelude::*,
system::{Commands, IntoSystem, Query, Res, ResMut, System},
system::{Commands, IntoSystem, Query, ReadOnlySystem, Res, ResMut, System},
};
use eframe::{
egui::{self, CursorIcon, Painter, Response, Sense, Ui},
emath::{Pos2, Rect, RectTransform, Vec2},
epaint::{color::Hsva, Color32, Stroke},
epaint::{Color32, Hsva, Stroke},
};
use geometry::{Line, LinePosQuery, Point, PointId, PointPos, PointPosQuery, PointPosQueryMut};
use iyes_loopless::prelude::*;
mod geometry;
mod optimization;
@ -20,15 +21,16 @@ fn main() {
"sketchrs",
options,
Box::new(|_cc| Box::new(MyApp::default())),
);
).unwrap();
}
#[derive(Clone, Copy, PartialEq)]
#[derive(Clone, Copy, PartialEq, Resource)]
enum Tool {
Select,
Move,
AddPoint,
AddLine,
AddRelation,
}
impl Default for Tool {
@ -37,6 +39,34 @@ impl Default for Tool {
}
}
#[derive(Resource)]
struct ResponseRes(Response);
impl Deref for ResponseRes {
type Target = Response;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[derive(Resource)]
struct PainterRes(Painter);
impl Deref for PainterRes {
type Target = Painter;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for PainterRes {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
#[derive(Resource)]
struct ToScreen(RectTransform);
impl ToScreen {
@ -73,7 +103,7 @@ fn color_for_var_status(status: geometry::VarStatus) -> Hsva {
const POINT_RADIUS: f32 = 3.0;
fn update_hover_point(
response: Res<Response>,
response: Res<ResponseRes>,
to_screen: Res<ToScreen>,
point_pos: PointPosQuery,
points: Query<(PointId, &Point)>,
@ -98,7 +128,7 @@ fn update_hover_point(
}
fn update_hover_line(
response: Res<Response>,
response: Res<ResponseRes>,
to_screen: Res<ToScreen>,
lines: Query<(Entity, &Line)>,
line_pos: LinePosQuery,
@ -129,45 +159,19 @@ fn update_hover_line(
});
}
fn update_cursor_icon(
response: Res<Response>,
tool: Res<Tool>,
hovered: Query<(), With<Hovered>>,
selected: Query<(), With<Selected>>,
) {
response.ctx.output().cursor_icon = match *tool {
Tool::Select => {
if !hovered.is_empty() {
CursorIcon::PointingHand
} else {
CursorIcon::Default
}
}
Tool::Move => {
if !selected.is_empty() {
CursorIcon::Grabbing
} else if !hovered.is_empty() {
CursorIcon::Grab
} else {
CursorIcon::Move
}
}
Tool::AddPoint => CursorIcon::None,
Tool::AddLine => CursorIcon::None,
};
}
fn select_tool(
response: Res<Response>,
response: Res<ResponseRes>,
hovered: Query<Entity, With<Hovered>>,
selected: Query<Entity, With<Selected>>,
mut commands: Commands,
) {
response.ctx.output().cursor_icon = if !hovered.is_empty() {
CursorIcon::PointingHand
} else {
CursorIcon::Default
};
response.ctx.output_mut(|output| {
output.cursor_icon = if !hovered.is_empty() {
CursorIcon::PointingHand
} else {
CursorIcon::Default
}
});
if response.clicked() {
selected.for_each(|selected| {
@ -185,7 +189,7 @@ struct DragDelta(Vec2);
// TODO: move other entities
fn move_tool(
response: Res<Response>,
response: Res<ResponseRes>,
to_screen: Res<ToScreen>,
mut drag_delta: Local<DragDelta>,
mut point_pos: PointPosQueryMut,
@ -195,13 +199,15 @@ fn move_tool(
) {
let hover_pos = response.hover_pos().unwrap();
response.ctx.output().cursor_icon = if !selected.is_empty() {
CursorIcon::Grabbing
} else if !hovered.is_empty() {
CursorIcon::Grab
} else {
CursorIcon::Move
};
response.ctx.output_mut(|o| {
o.cursor_icon = if !selected.is_empty() {
CursorIcon::Grabbing
} else if !hovered.is_empty() {
CursorIcon::Grab
} else {
CursorIcon::Move
}
});
let selected = if response.drag_started() {
// TODO: choose which to select
@ -237,9 +243,9 @@ fn add_point(commands: &mut Commands, pos: Pos2, to_screen: &ToScreen) -> PointI
}
fn add_point_tool(
response: Res<Response>,
response: Res<ResponseRes>,
to_screen: Res<ToScreen>,
painter: ResMut<egui::Painter>,
painter: ResMut<PainterRes>,
mut commands: Commands,
) {
let hover_pos = response.hover_pos().unwrap();
@ -251,9 +257,9 @@ fn add_point_tool(
}
fn add_line_tool(
response: Res<Response>,
response: Res<ResponseRes>,
to_screen: Res<ToScreen>,
painter: ResMut<egui::Painter>,
painter: ResMut<PainterRes>,
hovered: Query<Entity, (With<Hovered>, With<Point>)>,
selected: Query<(Entity, &Point), With<Selected>>,
point_pos: PointPosQuery,
@ -272,8 +278,8 @@ fn add_line_tool(
};
commands.entity(point_id).insert(Selected);
}
(Some(start_point), false) => {
let start_point_pos = point_pos.get(start_point.1);
(Some((_, start_point)), false) => {
let start_point_pos = point_pos.get(start_point);
let points = [to_screen.transform_pos(&start_point_pos), hover_pos];
let stroke = Stroke::new(2.0, Color32::DARK_GRAY);
@ -282,34 +288,60 @@ fn add_line_tool(
painter.circle_filled(hover_pos, POINT_RADIUS, Color32::DARK_GRAY);
}
(Some(start_point), true) => {
(Some((start_point_id, _)), true) => {
// TODO: add point if no hover point
let end_point = hovered
.iter()
.next()
.unwrap_or_else(|| add_point(&mut commands, hover_pos, &*to_screen));
let line = Line::new(start_point.0, end_point);
commands.spawn().insert(line);
let line = Line::new(start_point_id, end_point);
commands.spawn(line);
selected.for_each(|selected| {
commands.entity(selected.0).remove::<Selected>();
selected.for_each(|(selected_id, _)| {
commands.entity(selected_id).remove::<Selected>();
});
}
}
}
fn is_hovered(response: Res<Response>) -> bool {
fn add_relation_tool(
response: Res<ResponseRes>,
hovered: Query<Entity, With<Hovered>>,
selected: Query<Entity, With<Selected>>,
mut commands: Commands,
) {
response.ctx.output_mut(|o| {
o.cursor_icon = if !hovered.is_empty() {
CursorIcon::PointingHand
} else {
CursorIcon::Default
}
});
if response.clicked() {
// TODO: choose which to select
if let Some(hovered) = hovered.iter().next() {
commands.entity(hovered).insert(Selected);
} else {
selected.for_each(|selected| {
commands.entity(selected).remove::<Selected>();
});
}
}
}
fn is_hovered(response: Res<ResponseRes>) -> bool {
response.hover_pos().is_some()
}
fn is_tool_active(tool: Tool) -> impl System<In = (), Out = bool> {
fn is_tool_active(tool: Tool) -> impl System<In = (), Out = bool> + ReadOnlySystem {
IntoSystem::into_system(move |active_tool: Res<Tool>| *active_tool == tool)
}
fn paint_lines(
to_screen: Res<ToScreen>,
painter: ResMut<Painter>,
painter: ResMut<PainterRes>,
lines: Query<(Entity, &Line)>,
hovered: Query<(), With<Hovered>>,
selected: Query<(), With<Selected>>,
@ -336,7 +368,7 @@ fn paint_lines(
fn paint_points(
to_screen: Res<ToScreen>,
painter: ResMut<Painter>,
painter: ResMut<PainterRes>,
points: Query<(Entity, &Point)>,
hovered: Query<(), With<Hovered>>,
selected: Query<(), With<Selected>>,
@ -360,14 +392,15 @@ fn paint_points(
struct MyApp {
world: World,
show_entities_stage: SystemStage,
show_entities_stage: Schedule,
show_sidebar_stage: Schedule,
}
fn init(mut commands: Commands) {
let p1 = geometry::insert_point_at(&mut commands, (10., 30.));
let p2 = geometry::insert_point_at(&mut commands, (-20., 15.));
geometry::insert_point_at(&mut commands, (0., -10.));
commands.spawn().insert(Line::new(p1, p2));
commands.spawn(Line::new(p1, p2));
}
impl Default for MyApp {
@ -376,45 +409,52 @@ impl Default for MyApp {
world.init_resource::<Tool>();
let mut init_stage = SystemStage::single_threaded().with_system(init);
let mut init_stage = Schedule::new();
init_stage.add_system(init);
init_stage.run(&mut world);
Self {
world,
show_entities_stage: Self::create_show_entities_stage(),
show_sidebar_stage: Self::create_show_sidebar_stage(),
}
}
}
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
#[system_set(base)]
pub enum ScheduleSet {
Input,
Tools,
Paint,
}
impl MyApp {
fn create_show_entities_stage() -> SystemStage {
#[derive(SystemLabel, Debug, Clone, PartialEq, Eq, Hash)]
struct InputGroup;
#[derive(SystemLabel, Debug, Clone, PartialEq, Eq, Hash)]
struct ToolsGroup;
SystemStage::single_threaded()
.with_system_set(
ConditionSet::new()
.label("input")
.with_system(update_hover_point)
.with_system(update_hover_line)
.into(),
fn create_show_entities_stage() -> Schedule {
let mut schedule = Schedule::new();
schedule
.configure_sets((ScheduleSet::Input, ScheduleSet::Tools, ScheduleSet::Paint).chain());
schedule
.add_systems((update_hover_point, update_hover_line).in_base_set(ScheduleSet::Input));
schedule.add_systems(
(
select_tool.run_if(is_tool_active(Tool::Select)),
move_tool.run_if(is_tool_active(Tool::Move)),
add_point_tool.run_if(is_tool_active(Tool::AddPoint)),
add_line_tool.run_if(is_tool_active(Tool::AddLine)),
)
.with_system_set(
ConditionSet::new()
.label("tools")
.after("input")
.run_if(is_hovered)
.with_system(update_cursor_icon)
.with_system(select_tool.run_if(is_tool_active(Tool::Select)))
.with_system(move_tool.run_if(is_tool_active(Tool::Move)))
.with_system(add_point_tool.run_if(is_tool_active(Tool::AddPoint)))
.with_system(add_line_tool.run_if(is_tool_active(Tool::AddLine)))
.into(),
)
.with_system(paint_lines.label("paint_lines").after("tools")) // TODO order dependency
.with_system(paint_points.after("paint_lines"))
.distributive_run_if(is_hovered)
.in_base_set(ScheduleSet::Tools),
);
schedule.add_systems(
(paint_lines, paint_points.after(paint_lines)).in_base_set(ScheduleSet::Paint),
);
schedule
}
fn create_show_sidebar_stage() -> Schedule {
let mut schedule = Schedule::new();
schedule
}
fn show_toolbar(&mut self, ui: &mut Ui) {
@ -429,13 +469,14 @@ impl MyApp {
ui.selectable_value(tool, Tool::Move, "Move");
ui.selectable_value(tool, Tool::AddPoint, "+ Point");
ui.selectable_value(tool, Tool::AddLine, "+ Line");
ui.selectable_value(tool, Tool::AddRelation, "+ Relation");
});
}
fn show_entities(&mut self, ui: &mut Ui) {
let sense = match *self.world.resource::<Tool>() {
Tool::Move => Sense::drag(),
Tool::Select | Tool::AddPoint | Tool::AddLine => Sense::click(),
Tool::Select | Tool::AddPoint | Tool::AddLine | Tool::AddRelation => Sense::click(),
};
let (response, painter) = ui.allocate_painter(ui.available_size(), sense);
@ -444,13 +485,13 @@ impl MyApp {
response.rect,
));
self.world.insert_resource(to_screen);
self.world.insert_resource(response);
self.world.insert_resource(painter);
self.world.insert_resource(ResponseRes(response));
self.world.insert_resource(PainterRes(painter));
self.show_entities_stage.run(&mut self.world);
self.world.remove_resource::<Painter>();
self.world.remove_resource::<Response>();
self.world.remove_resource::<PainterRes>();
self.world.remove_resource::<ResponseRes>();
self.world.remove_resource::<ToScreen>();
}
@ -465,15 +506,24 @@ impl MyApp {
selected.for_each(&self.world, |(id, point, line)| {
count += 1;
if point.is_some() {
ui.label(format!("Selected point {}", id.id()));
ui.label(format!("Selected point {}", id.index()));
} else if line.is_some() {
ui.label(format!("Selected line {}", id.id()));
ui.label(format!("Selected line {}", id.index()));
}
});
if count == 0 {
ui.label("No selection");
}
}
Tool::AddRelation => {
let mut selected = self
.world
.query_filtered::<(Entity, Option<&Point>, Option<&Line>), With<Selected>>();
if let Some(first) = selected.iter(&self.world).next() {
} else {
ui.label("Select an entity to add a relation");
}
}
_ => {
ui.label(":)");
}