diff --git a/rmf_site_editor/src/lib.rs b/rmf_site_editor/src/lib.rs index ca4f8a29..4cc6b2fd 100644 --- a/rmf_site_editor/src/lib.rs +++ b/rmf_site_editor/src/lib.rs @@ -56,6 +56,9 @@ pub mod site_asset_io; pub mod urdf_loader; use sdf_loader::*; +pub mod wireframe; +use wireframe::*; + use aabb::AabbUpdatePlugin; use animate::AnimationPlugin; use interaction::InteractionPlugin; @@ -222,6 +225,7 @@ impl Plugin for SiteEditor { .add_plugin(InteractionPlugin) .add_plugin(StandardUiLayout) .add_plugin(AnimationPlugin) + .add_plugin(SiteWireframePlugin) .add_plugin(OccupancyPlugin) .add_plugin(WorkspacePlugin) // Note order matters, issue and OSMView plugins must be initialized after the UI diff --git a/rmf_site_editor/src/wireframe.rs b/rmf_site_editor/src/wireframe.rs new file mode 100644 index 00000000..8097946b --- /dev/null +++ b/rmf_site_editor/src/wireframe.rs @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2023 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + +use crate::menu_bar::{MenuEvent, MenuItem, ViewMenu}; +use bevy::pbr::wireframe::{Wireframe, WireframePlugin}; +use bevy::prelude::*; + +use rmf_site_format::ModelMarker; + +#[derive(Default)] +pub struct SiteWireframePlugin; + +/// Keeps track of which entity is associated to the toggle menu button +#[derive(Resource)] +pub struct WireframeMenu { + toggle_wireframe: Entity, +} + +impl FromWorld for WireframeMenu { + fn from_world(world: &mut World) -> Self { + // Tools menu + let toggle_wireframe = world + .spawn(MenuItem::CheckBox("View wireframe".to_string(), false)) + .id(); + + let view_header = world.resource::().get(); + world + .entity_mut(view_header) + .push_children(&[toggle_wireframe]); + + WireframeMenu { toggle_wireframe } + } +} + +fn handle_wireframe_menu_events( + mut commands: Commands, + mut menu_events: EventReader, + mut menu_items: Query<&mut MenuItem>, + wireframe_menu: Res, + meshes: Query>>, + parents: Query<&Parent>, + children: Query<&Children>, + models: Query>, +) { + for event in menu_events.iter() { + if event.clicked() && event.source() == wireframe_menu.toggle_wireframe { + let Ok(mut checkbox) = menu_items.get_mut(wireframe_menu.toggle_wireframe) else { + error!("Wireframe button not found"); + return; + }; + let MenuItem::CheckBox(_, ref mut enable) = *checkbox else { + error!("Mismatch for wireframe toggle menu type, expected checkbox"); + return; + }; + *enable = !*enable; + for model in models.iter() { + // Now go through all the model children and toggle wireframe on meshes + for c in DescendantIter::new(&children, model) { + if meshes.get(c).is_ok() { + if *enable { + commands.entity(c).insert(Wireframe); + } else { + commands.entity(c).remove::(); + } + } + } + } + } + } +} + +impl Plugin for SiteWireframePlugin { + fn build(&self, app: &mut App) { + app.init_resource::() + .add_plugin(WireframePlugin) + .add_system(handle_wireframe_menu_events); + } +} diff --git a/rmf_site_editor/src/workcell/mod.rs b/rmf_site_editor/src/workcell/mod.rs index 8481b7b2..c6963eed 100644 --- a/rmf_site_editor/src/workcell/mod.rs +++ b/rmf_site_editor/src/workcell/mod.rs @@ -33,7 +33,6 @@ pub use workcell::*; pub mod urdf; pub use urdf::*; -use bevy::pbr::wireframe::{Wireframe, WireframePlugin}; use bevy::render::{render_resource::WgpuFeatures, settings::WgpuSettings}; use bevy::{prelude::*, render::view::visibility::VisibilitySystems, transform::TransformSystem}; use bevy_infinite_grid::{InfiniteGrid, InfiniteGridBundle, InfiniteGridPlugin}; @@ -68,21 +67,6 @@ fn delete_grid(mut commands: Commands, grids: Query>) } } -fn add_wireframe_to_meshes( - mut commands: Commands, - new_meshes: Query>>, - parents: Query<&Parent>, - models: Query>, -) { - for e in new_meshes.iter() { - for ancestor in AncestorIter::new(&parents, e) { - if let Ok(_) = models.get(ancestor) { - commands.entity(e).insert(Wireframe); - } - } - } -} - impl Plugin for WorkcellEditorPlugin { fn build(&self, app: &mut App) { app.add_plugin(InfiniteGridPlugin) @@ -90,7 +74,6 @@ impl Plugin for WorkcellEditorPlugin { features: WgpuFeatures::POLYGON_MODE_LINE, ..default() }) - .add_plugin(WireframePlugin) .add_plugin(RapierPhysicsPlugin::::default()) .add_plugin(RapierDebugRenderPlugin::default()) .add_event::() @@ -100,7 +83,6 @@ impl Plugin for WorkcellEditorPlugin { .add_system_set(SystemSet::on_exit(AppState::WorkcellEditor).with_system(delete_grid)) .add_system_set( SystemSet::on_update(AppState::WorkcellEditor) - .with_system(add_wireframe_to_meshes) .with_system(update_constraint_dependents) .with_system(handle_model_loaded_events) .with_system(update_model_scenes)