From 7fe7e0230d264d7decdf0cccea5227dac47c1c81 Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Tue, 16 Jun 2026 11:33:46 +0300 Subject: [PATCH] refactor(scene): group modules into role-based subfolders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the 30 flat modules under src/scene/ into six folders by role: convert (entity→geometry), text (fonts/shaping), model (render models), pick (hit-test/selection/grips/xclip), view (camera/transform/render), cache (block + property caches). pipeline/ is unchanged. Full path migration — all `scene::X` references become `scene::::X`, no compatibility re-exports. render.rs items that were `pub(super)` (parent was scene) become `pub(in crate::scene)` to keep their original scene-wide visibility. No behavior change; build and tests are green. Co-Authored-By: Claude Opus 4.8 --- src/app/cmd_result.rs | 42 ++-- src/app/document.rs | 2 +- src/app/mod.rs | 4 +- src/app/model_ops.rs | 2 +- src/app/mtext_editor.rs | 4 +- src/app/properties.rs | 62 +++--- src/app/update.rs | 78 +++---- src/app/view.rs | 4 +- src/app/visibility.rs | 2 +- src/command/mod.rs | 6 +- src/entities/arc.rs | 28 +-- src/entities/attribute.rs | 9 +- src/entities/circle.rs | 14 +- src/entities/common.rs | 2 +- src/entities/dimension.rs | 42 ++-- src/entities/ellipse.rs | 12 +- src/entities/hatch.rs | 26 +-- src/entities/insert.rs | 14 +- src/entities/leader.rs | 32 +-- src/entities/line.rs | 30 +-- src/entities/lwpolyline.rs | 26 +-- src/entities/mesh.rs | 22 +- src/entities/mline.rs | 20 +- src/entities/mtext.rs | 24 +-- src/entities/multileader.rs | 42 ++-- src/entities/ole2frame.rs | 8 +- src/entities/point.rs | 12 +- src/entities/polyline.rs | 44 ++-- src/entities/raster_image.rs | 12 +- src/entities/ray.rs | 12 +- src/entities/shape.rs | 8 +- src/entities/solid.rs | 10 +- src/entities/solid3d.rs | 6 +- src/entities/spline.rs | 18 +- src/entities/table.rs | 14 +- src/entities/text.rs | 30 +-- src/entities/text_support.rs | 6 +- src/entities/tolerance.rs | 9 +- src/entities/traits.rs | 18 +- src/entities/underlay.rs | 8 +- src/entities/viewport.rs | 8 +- src/io/obj.rs | 2 +- src/io/pdf_export.rs | 2 +- src/io/print_to_printer.rs | 2 +- src/io/step.rs | 2 +- src/io/stl.rs | 2 +- src/modules/annotate/aligned_dim.rs | 2 +- src/modules/annotate/angular_dim.rs | 2 +- src/modules/annotate/diameter_dim.rs | 2 +- src/modules/annotate/dim_baseline.rs | 2 +- src/modules/annotate/dim_continue.rs | 2 +- src/modules/annotate/dimjogline.rs | 2 +- src/modules/annotate/dimtedit.rs | 2 +- src/modules/annotate/leader_cmd.rs | 2 +- src/modules/annotate/linear_dim.rs | 2 +- src/modules/annotate/mleader_cmd.rs | 2 +- src/modules/annotate/mleader_edit.rs | 2 +- src/modules/annotate/mtext.rs | 2 +- src/modules/annotate/ordinate_dim.rs | 2 +- src/modules/annotate/qdim.rs | 2 +- src/modules/annotate/radius_dim.rs | 2 +- src/modules/annotate/table_cmd.rs | 2 +- src/modules/annotate/text.rs | 2 +- src/modules/annotate/tolerance_cmd.rs | 2 +- src/modules/home/clipboard/paste.rs | 2 +- src/modules/home/draw/arc.rs | 2 +- src/modules/home/draw/attdef.rs | 2 +- src/modules/home/draw/circle.rs | 2 +- src/modules/home/draw/ellipse.rs | 2 +- src/modules/home/draw/hatch.rs | 6 +- src/modules/home/draw/line.rs | 2 +- src/modules/home/draw/mline.rs | 2 +- src/modules/home/draw/point.rs | 2 +- src/modules/home/draw/polyline.rs | 2 +- src/modules/home/draw/raster_image.rs | 2 +- src/modules/home/draw/ray.rs | 2 +- src/modules/home/draw/revcloud.rs | 2 +- src/modules/home/draw/shapes.rs | 2 +- src/modules/home/draw/spline.rs | 2 +- src/modules/home/draw/wipeout.rs | 2 +- src/modules/home/groups/group.rs | 2 +- src/modules/home/groups/ungroup.rs | 2 +- src/modules/home/inquiry/area.rs | 2 +- src/modules/home/inquiry/dist.rs | 2 +- src/modules/home/layers/match_layer.rs | 2 +- src/modules/home/modify/array.rs | 8 +- src/modules/home/modify/attedit.rs | 2 +- src/modules/home/modify/break_cmd.rs | 2 +- src/modules/home/modify/copy.rs | 2 +- src/modules/home/modify/fillet.rs | 2 +- src/modules/home/modify/mirror.rs | 2 +- src/modules/home/modify/offset.rs | 2 +- src/modules/home/modify/refedit.rs | 4 +- src/modules/home/modify/rotate.rs | 2 +- src/modules/home/modify/scale.rs | 2 +- src/modules/home/modify/splinedit.rs | 2 +- src/modules/home/modify/stretch.rs | 2 +- src/modules/home/modify/translate.rs | 2 +- src/modules/home/modify/trim.rs | 2 +- src/modules/home/properties/match_prop.rs | 2 +- src/modules/home/select.rs | 2 +- src/modules/insert/create_block.rs | 2 +- src/modules/insert/insert_block.rs | 2 +- src/modules/insert/xattach.rs | 2 +- src/modules/layout/mview.rs | 2 +- src/modules/layout/vplayer.rs | 2 +- src/modules/manage/mview.rs | 2 +- src/modules/model/primitive_cmd.rs | 4 +- src/modules/view/plot_window.rs | 2 +- src/modules/view/zoom_window.rs | 2 +- src/scene/{ => cache}/block_cache.rs | 10 +- src/scene/cache/mod.rs | 2 + src/scene/{ => cache}/properties.rs | 2 +- src/scene/{ => convert}/acad_to_truck.rs | 2 +- src/scene/{ => convert}/acis_to_truck.rs | 8 +- src/scene/convert/mod.rs | 7 + src/scene/{ => convert}/solid3d_tess.rs | 6 +- src/scene/{ => convert}/spline_tess.rs | 2 +- src/scene/{ => convert}/tess_util.rs | 6 +- src/scene/{ => convert}/tessellate.rs | 8 +- src/scene/{ => convert}/truck_tess.rs | 0 src/scene/mod.rs | 246 ++++++++++------------ src/scene/{ => model}/hatch_model.rs | 0 src/scene/{ => model}/hatch_patterns.rs | 2 +- src/scene/{ => model}/image_model.rs | 0 src/scene/{ => model}/mesh_model.rs | 0 src/scene/model/mod.rs | 7 + src/scene/{ => model}/model_solid.rs | 6 +- src/scene/{ => model}/object.rs | 0 src/scene/{ => model}/wire_model.rs | 0 src/scene/{ => pick}/grip.rs | 2 +- src/scene/{ => pick}/hit_test.rs | 6 +- src/scene/pick/mod.rs | 5 + src/scene/{ => pick}/quadtree.rs | 0 src/scene/{ => pick}/selection.rs | 0 src/scene/{ => pick}/xclip.rs | 4 +- src/scene/pipeline/face3d_gpu.rs | 2 +- src/scene/pipeline/hatch_batched_gpu.rs | 2 +- src/scene/pipeline/hatch_gpu.rs | 2 +- src/scene/pipeline/image_gpu.rs | 2 +- src/scene/pipeline/mesh_gpu.rs | 2 +- src/scene/pipeline/mod.rs | 8 +- src/scene/pipeline/uniforms.rs | 2 +- src/scene/pipeline/wire_gpu.rs | 2 +- src/scene/{ => text}/complex_lt.rs | 4 +- src/scene/{ => text}/font_face.rs | 4 +- src/scene/{ => text}/lff.rs | 56 ++--- src/scene/text/mod.rs | 5 + src/scene/{ => text}/sysfont.rs | 0 src/scene/{ => text}/ttf_glyph.rs | 4 +- src/scene/{ => view}/camera.rs | 0 src/scene/{ => view}/dispatch.rs | 6 +- src/scene/view/mod.rs | 5 + src/scene/{ => view}/render.rs | 72 +++---- src/scene/{ => view}/transform.rs | 0 src/scene/{ => view}/viewport_pane.rs | 2 +- src/snap/mod.rs | 2 +- src/ui/overlay.rs | 4 +- src/ui/properties.rs | 4 +- src/ui/textstyle.rs | 2 +- 160 files changed, 732 insertions(+), 715 deletions(-) rename src/scene/{ => cache}/block_cache.rs (99%) create mode 100644 src/scene/cache/mod.rs rename src/scene/{ => cache}/properties.rs (96%) rename src/scene/{ => convert}/acad_to_truck.rs (97%) rename src/scene/{ => convert}/acis_to_truck.rs (98%) create mode 100644 src/scene/convert/mod.rs rename src/scene/{ => convert}/solid3d_tess.rs (99%) rename src/scene/{ => convert}/spline_tess.rs (99%) rename src/scene/{ => convert}/tess_util.rs (95%) rename src/scene/{ => convert}/tessellate.rs (99%) rename src/scene/{ => convert}/truck_tess.rs (100%) rename src/scene/{ => model}/hatch_model.rs (100%) rename src/scene/{ => model}/hatch_patterns.rs (98%) rename src/scene/{ => model}/image_model.rs (100%) rename src/scene/{ => model}/mesh_model.rs (100%) create mode 100644 src/scene/model/mod.rs rename src/scene/{ => model}/model_solid.rs (97%) rename src/scene/{ => model}/object.rs (100%) rename src/scene/{ => model}/wire_model.rs (100%) rename src/scene/{ => pick}/grip.rs (98%) rename src/scene/{ => pick}/hit_test.rs (99%) create mode 100644 src/scene/pick/mod.rs rename src/scene/{ => pick}/quadtree.rs (100%) rename src/scene/{ => pick}/selection.rs (100%) rename src/scene/{ => pick}/xclip.rs (99%) rename src/scene/{ => text}/complex_lt.rs (99%) rename src/scene/{ => text}/font_face.rs (98%) rename src/scene/{ => text}/lff.rs (93%) create mode 100644 src/scene/text/mod.rs rename src/scene/{ => text}/sysfont.rs (100%) rename src/scene/{ => text}/ttf_glyph.rs (99%) rename src/scene/{ => view}/camera.rs (100%) rename src/scene/{ => view}/dispatch.rs (94%) create mode 100644 src/scene/view/mod.rs rename src/scene/{ => view}/render.rs (94%) rename src/scene/{ => view}/transform.rs (100%) rename src/scene/{ => view}/viewport_pane.rs (99%) diff --git a/src/app/cmd_result.rs b/src/app/cmd_result.rs index 9a1d3f220..9d0d103a6 100644 --- a/src/app/cmd_result.rs +++ b/src/app/cmd_result.rs @@ -523,8 +523,8 @@ impl OpenCADStudio { for h in &dest { if let Some(e) = self.tabs[i].scene.document.get_entity_mut(*h) { e.as_entity_mut().set_layer(layer.clone()); - crate::scene::dispatch::apply_color(e, color); - crate::scene::dispatch::apply_line_weight(e, lw); + crate::scene::view::dispatch::apply_color(e, color); + crate::scene::view::dispatch::apply_line_weight(e, lw); e.common_mut().linetype = linetype.clone(); e.common_mut().linetype_scale = lt_scale; } @@ -553,7 +553,7 @@ impl OpenCADStudio { .clone() .into_iter() .map(|mut entity| { - crate::scene::dispatch::apply_transform(&mut entity, &translate); + crate::scene::view::dispatch::apply_transform(&mut entity, &translate); entity.common_mut().handle = acadrust::Handle::NULL; self.tabs[i].scene.add_entity(entity) }) @@ -1170,8 +1170,8 @@ impl OpenCADStudio { } => { use crate::entities::traits::EntityTypeOps; use crate::modules::insert::solid3d_cmds::empty_solid3d; - use crate::scene::acad_to_truck::TruckObject; - use crate::scene::truck_tess; + use crate::scene::convert::acad_to_truck::TruckObject; + use crate::scene::convert::truck_tess; use truck_modeling::builder; use truck_modeling::Vector3 as TruckVec3; @@ -1192,7 +1192,7 @@ impl OpenCADStudio { verts, normals, indices, - } => Some(crate::scene::mesh_model::MeshModel { + } => Some(crate::scene::model::mesh_model::MeshModel { name: String::new(), verts, normals, @@ -1236,8 +1236,8 @@ impl OpenCADStudio { } => { use crate::entities::traits::EntityTypeOps; use crate::modules::insert::solid3d_cmds::empty_solid3d; - use crate::scene::acad_to_truck::TruckObject; - use crate::scene::truck_tess; + use crate::scene::convert::acad_to_truck::TruckObject; + use crate::scene::convert::truck_tess; use truck_modeling::builder; use truck_modeling::{Point3, Rad, Vector3 as TruckVec3}; @@ -1270,7 +1270,7 @@ impl OpenCADStudio { verts, normals, indices, - } => Some(crate::scene::mesh_model::MeshModel { + } => Some(crate::scene::model::mesh_model::MeshModel { name: String::new(), verts, normals, @@ -1311,8 +1311,8 @@ impl OpenCADStudio { } => { use crate::entities::traits::EntityTypeOps; use crate::modules::insert::solid3d_cmds::empty_solid3d; - use crate::scene::acad_to_truck::TruckObject; - use crate::scene::truck_tess; + use crate::scene::convert::acad_to_truck::TruckObject; + use crate::scene::convert::truck_tess; use truck_modeling::builder; use truck_modeling::Vector3 as TruckVec3; @@ -1355,7 +1355,7 @@ impl OpenCADStudio { verts, normals, indices, - } => Some(crate::scene::mesh_model::MeshModel { + } => Some(crate::scene::model::mesh_model::MeshModel { name: String::new(), verts, normals, @@ -1372,7 +1372,7 @@ impl OpenCADStudio { verts, normals, indices, - } => Some(crate::scene::mesh_model::MeshModel { + } => Some(crate::scene::model::mesh_model::MeshModel { name: String::new(), verts, normals, @@ -1404,7 +1404,7 @@ impl OpenCADStudio { verts, normals, indices, - } => Some(crate::scene::mesh_model::MeshModel { + } => Some(crate::scene::model::mesh_model::MeshModel { name: String::new(), verts, normals, @@ -1421,7 +1421,7 @@ impl OpenCADStudio { verts, normals, indices, - } => Some(crate::scene::mesh_model::MeshModel { + } => Some(crate::scene::model::mesh_model::MeshModel { name: String::new(), verts, normals, @@ -1460,8 +1460,8 @@ impl OpenCADStudio { CmdResult::LoftEntities { handles, color } => { use crate::entities::traits::EntityTypeOps; use crate::modules::insert::solid3d_cmds::empty_solid3d; - use crate::scene::acad_to_truck::TruckObject; - use crate::scene::truck_tess; + use crate::scene::convert::acad_to_truck::TruckObject; + use crate::scene::convert::truck_tess; use truck_modeling::builder; // Collect wires from each profile. @@ -1482,7 +1482,7 @@ impl OpenCADStudio { } let woff = self.tabs[i].scene.world_offset; - let result: Option = (|| { + let result: Option = (|| { if wires.len() < 2 { return None; } @@ -1511,7 +1511,7 @@ impl OpenCADStudio { verts, normals, indices, - } => Some(crate::scene::mesh_model::MeshModel { + } => Some(crate::scene::model::mesh_model::MeshModel { name: String::new(), verts, normals, @@ -1552,8 +1552,8 @@ impl OpenCADStudio { if let Some(mut model) = self.tabs[i].scene.hatches.get(&handle).cloned() { // Update model fields if !name.is_empty() { - use crate::scene::hatch_model::HatchPattern; - use crate::scene::hatch_patterns; + use crate::scene::model::hatch_model::HatchPattern; + use crate::scene::model::hatch_patterns; model.name = name.clone(); if name.to_uppercase() == "SOLID" { model.pattern = HatchPattern::Solid; diff --git a/src/app/document.rs b/src/app/document.rs index 7fd933d5a..e347ac65f 100644 --- a/src/app/document.rs +++ b/src/app/document.rs @@ -1,7 +1,7 @@ use crate::command::CadCommand; use crate::linetypes; use crate::modules::home::modify::refedit::RefEditSession; -use crate::scene::grip::GripEdit; +use crate::scene::pick::grip::GripEdit; use crate::scene::GripDef; use crate::scene::Scene; use crate::snap::SnapResult; diff --git a/src/app/mod.rs b/src/app/mod.rs index adac19472..ae19fe7e2 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -50,7 +50,7 @@ pub struct GripPopup { pub handle: acadrust::Handle, pub grip_id: usize, pub anchor: iced::Point, - pub items: Vec, + pub items: Vec, pub selected: usize, } @@ -62,7 +62,7 @@ pub struct GripPopup { pub struct GripPendingValue { pub handle: acadrust::Handle, pub grip_id: usize, - pub action: crate::scene::object::GripMenuAction, + pub action: crate::scene::model::object::GripMenuAction, pub label: &'static str, } diff --git a/src/app/model_ops.rs b/src/app/model_ops.rs index 61764b70f..4109c6012 100644 --- a/src/app/model_ops.rs +++ b/src/app/model_ops.rs @@ -9,7 +9,7 @@ use truck_modeling::Solid; use super::Message; use crate::modules::model::boolean_cmd::BoolOp; -use crate::scene::model_solid::{self, Bool}; +use crate::scene::model::model_solid::{self, Bool}; impl super::OpenCADStudio { /// Commit a Model-tab solid: add its acadrust entity to the document, then diff --git a/src/app/mtext_editor.rs b/src/app/mtext_editor.rs index 16ae076f9..3efc39c93 100644 --- a/src/app/mtext_editor.rs +++ b/src/app/mtext_editor.rs @@ -323,8 +323,8 @@ pub fn visible_spans(raw: &str) -> Vec<(usize, usize)> { // ── App-side editor driver ────────────────────────────────────────────────── -use crate::scene::tessellate; -use crate::scene::wire_model::WireModel; +use crate::scene::convert::tessellate; +use crate::scene::model::wire_model::WireModel; use iced::widget::text_editor::{Action, Edit}; use std::sync::Arc; diff --git a/src/app/properties.rs b/src/app/properties.rs index 335326221..5afbf1762 100644 --- a/src/app/properties.rs +++ b/src/app/properties.rs @@ -1,7 +1,7 @@ use super::helpers::{entity_type_key, entity_type_label, title_case_word}; use super::{OpenCADStudio, VARIES_LABEL}; use crate::linetypes; -use crate::scene::dispatch; +use crate::scene::view::dispatch; use crate::ui; use acadrust::{EntityType, Handle}; @@ -118,28 +118,28 @@ impl OpenCADStudio { .collect(); if let Some(geom) = sections.last_mut() { - geom.props.push(crate::scene::object::Property { + geom.props.push(crate::scene::model::object::Property { label: "Frozen Layers".to_string(), field: "frozen_layers", - value: crate::scene::object::PropValue::EditText( + value: crate::scene::model::object::PropValue::EditText( frozen_names.join(", "), ), }); if !ucs_names.is_empty() { - geom.props.push(crate::scene::object::Property { + geom.props.push(crate::scene::model::object::Property { label: "UCS Name".to_string(), field: "vp_ucs_name", - value: crate::scene::object::PropValue::Choice { + value: crate::scene::model::object::PropValue::Choice { selected: current_ucs, options: ucs_names, }, }); } if !view_names.is_empty() { - geom.props.push(crate::scene::object::Property { + geom.props.push(crate::scene::model::object::Property { label: "Named View".to_string(), field: "vp_named_view", - value: crate::scene::object::PropValue::Choice { + value: crate::scene::model::object::PropValue::Choice { selected: String::new(), options: view_names, }, @@ -167,7 +167,7 @@ impl OpenCADStudio { if let Some(prop) = geom.props.iter_mut().find(|p| p.field == "vscale_std") { - prop.value = crate::scene::object::PropValue::Choice { + prop.value = crate::scene::model::object::PropValue::Choice { selected, options, }; @@ -195,10 +195,10 @@ impl OpenCADStudio { geom.props.iter_mut().find(|p| p.field == "style_name") { let current = match &prop.value { - crate::scene::object::PropValue::EditText(s) => s.clone(), + crate::scene::model::object::PropValue::EditText(s) => s.clone(), _ => String::new(), }; - prop.value = crate::scene::object::PropValue::Choice { + prop.value = crate::scene::model::object::PropValue::Choice { selected: current, options: dim_style_names, }; @@ -210,10 +210,10 @@ impl OpenCADStudio { if !group_names.is_empty() { let label = group_names.join(", "); if let Some(general) = sections.first_mut() { - general.props.push(crate::scene::object::Property { + general.props.push(crate::scene::model::object::Property { label: "Group".to_string(), field: "group", - value: crate::scene::object::PropValue::ReadOnly(label), + value: crate::scene::model::object::PropValue::ReadOnly(label), }); } } @@ -240,7 +240,7 @@ impl OpenCADStudio { .iter() .flat_map(|section| section.props.iter()) .filter_map(|prop| match &prop.value { - crate::scene::object::PropValue::Choice { options, .. } => Some(( + crate::scene::model::object::PropValue::Choice { options, .. } => Some(( prop.field.to_string(), iced::widget::combo_box::State::new(options.clone()), )), @@ -252,7 +252,7 @@ impl OpenCADStudio { layer_combo: iced::widget::combo_box::State::new(layer_names.clone()), linetype_combo: iced::widget::combo_box::State::new(linetype_items.clone()), hatch_pattern_combo: iced::widget::combo_box::State::new( - crate::scene::hatch_patterns::names(), + crate::scene::model::hatch_patterns::names(), ), lineweight_combo: iced::widget::combo_box::State::new( ui::properties::lw_options(), @@ -284,7 +284,7 @@ impl OpenCADStudio { .iter() .flat_map(|section| section.props.iter()) .filter_map(|prop| match &prop.value { - crate::scene::object::PropValue::Choice { options, .. } => Some(( + crate::scene::model::object::PropValue::Choice { options, .. } => Some(( prop.field.to_string(), iced::widget::combo_box::State::new(options.clone()), )), @@ -299,7 +299,7 @@ impl OpenCADStudio { layer_combo: iced::widget::combo_box::State::new(layer_names.clone()), linetype_combo: iced::widget::combo_box::State::new(linetype_items.clone()), hatch_pattern_combo: iced::widget::combo_box::State::new( - crate::scene::hatch_patterns::names(), + crate::scene::model::hatch_patterns::names(), ), lineweight_combo: iced::widget::combo_box::State::new( ui::properties::lw_options(), @@ -527,13 +527,13 @@ impl OpenCADStudio { } } - crate::scene::dispatch::apply_color(&mut entity, self.ribbon.active_color); - crate::scene::dispatch::apply_common_prop( + crate::scene::view::dispatch::apply_color(&mut entity, self.ribbon.active_color); + crate::scene::view::dispatch::apply_common_prop( &mut entity, "linetype", &self.ribbon.active_linetype.clone(), ); - crate::scene::dispatch::apply_line_weight(&mut entity, self.ribbon.active_lineweight); + crate::scene::view::dispatch::apply_line_weight(&mut entity, self.ribbon.active_lineweight); // CELTSCALE (header.current_entity_linetype_scale): new entities // pick up the document's saved per-entity linetype scale. The user // can override per entity later via the properties panel. @@ -741,12 +741,12 @@ pub(super) fn build_selection_groups( pub(super) fn aggregate_sections( selected: &[(Handle, &EntityType)], text_style_names: &[String], -) -> Vec { +) -> Vec { if selected.is_empty() { return vec![]; } - let mut all_sections: Vec> = selected + let mut all_sections: Vec> = selected .iter() .map(|(handle, entity)| dispatch::properties_sectioned(*handle, entity, text_style_names)) .collect(); @@ -759,15 +759,15 @@ pub(super) fn aggregate_sections( } fn merge_sections( - left: &[crate::scene::object::PropSection], - right: &[crate::scene::object::PropSection], -) -> Vec { + left: &[crate::scene::model::object::PropSection], + right: &[crate::scene::model::object::PropSection], +) -> Vec { left.iter() .filter_map(|section| { let rhs = right .iter() .find(|candidate| candidate.title == section.title)?; - let props: Vec = section + let props: Vec = section .props .iter() .filter_map(|prop| { @@ -775,7 +775,7 @@ fn merge_sections( .props .iter() .find(|candidate| candidate.field == prop.field)?; - Some(crate::scene::object::Property { + Some(crate::scene::model::object::Property { label: prop.label.clone(), field: prop.field, value: merge_prop_value(&prop.value, &other.value), @@ -785,7 +785,7 @@ fn merge_sections( if props.is_empty() { None } else { - Some(crate::scene::object::PropSection { + Some(crate::scene::model::object::PropSection { title: section.title.clone(), props, }) @@ -795,10 +795,10 @@ fn merge_sections( } fn merge_prop_value( - left: &crate::scene::object::PropValue, - right: &crate::scene::object::PropValue, -) -> crate::scene::object::PropValue { - use crate::scene::object::PropValue; + left: &crate::scene::model::object::PropValue, + right: &crate::scene::model::object::PropValue, +) -> crate::scene::model::object::PropValue { + use crate::scene::model::object::PropValue; if left == right { return left.clone(); diff --git a/src/app/update.rs b/src/app/update.rs index abc60ecbc..ffd31daba 100644 --- a/src/app/update.rs +++ b/src/app/update.rs @@ -4,8 +4,8 @@ use super::helpers::{ }; use super::{Message, OpenCADStudio, POLY_START_DELAY_MS}; use crate::modules::ModuleEvent; -use crate::scene::grip::{find_hit_grip, find_hit_grip_paper, GripEdit}; -use crate::scene::object::GripApply; +use crate::scene::pick::grip::{find_hit_grip, find_hit_grip_paper, GripEdit}; +use crate::scene::model::object::GripApply; use crate::scene::{ self, hover_id, Scene, TileEdgeOrient, VIEWCUBE_DRAW_PX, VIEWCUBE_PAD, VIEWCUBE_PX, }; @@ -552,13 +552,13 @@ impl OpenCADStudio { // STL gets the highest-resolution LOD (slot 0) so the // exported geometry isn't downgraded by the view-dependent // mesh LOD ladder used for rendering. - let meshes: Vec = self.tabs[i] + let meshes: Vec = self.tabs[i] .scene .meshes .values() .filter_map(|s| s.lods.first().cloned()) .collect(); - let mesh_refs: Vec<&crate::scene::mesh_model::MeshModel> = meshes.iter().collect(); + let mesh_refs: Vec<&crate::scene::model::mesh_model::MeshModel> = meshes.iter().collect(); match crate::io::stl::build_stl(&mesh_refs) { Some(bytes) => match std::fs::write(&path, bytes) { Ok(()) => self @@ -603,13 +603,13 @@ impl OpenCADStudio { Message::StepExportPath(Some(path)) => { let i = self.active_tab; // Export uses LOD 0 (full resolution); see StlExportPath above. - let meshes: Vec = self.tabs[i] + let meshes: Vec = self.tabs[i] .scene .meshes .values() .filter_map(|s| s.lods.first().cloned()) .collect(); - let mesh_refs: Vec<&crate::scene::mesh_model::MeshModel> = meshes.iter().collect(); + let mesh_refs: Vec<&crate::scene::model::mesh_model::MeshModel> = meshes.iter().collect(); match crate::io::step::build_step(&mesh_refs) { Some(text) => match std::fs::write(&path, text.as_bytes()) { Ok(()) => self @@ -1435,7 +1435,7 @@ impl OpenCADStudio { if let Some(e) = self.tabs[i].scene.document.get_entity_mut(h) { e.apply_grip_menu( gid, - crate::scene::object::GripMenuAction::RemoveLeader, + crate::scene::model::object::GripMenuAction::RemoveLeader, ); } self.tabs[i].scene.bump_geometry(); @@ -2121,7 +2121,7 @@ impl OpenCADStudio { // Multi-functional grip hover: detect cursor sitting on a // selected entity's grip and, after a dwell, open the - // popup menu. See scene::object::GripMenuItem. + // popup menu. See scene::model::object::GripMenuItem. self.update_grip_hover(i, p); let mut sel = self.tabs[i].scene.selection.borrow_mut(); @@ -2405,7 +2405,7 @@ impl OpenCADStudio { }; let view_proj = self.tabs[i].scene.camera.borrow().view_proj(bounds); let all_wires = self.tabs[i].scene.hit_test_wires(); - let hovered = scene::hit_test::click_hit(p, &all_wires[..], view_proj, bounds) + let hovered = scene::pick::hit_test::click_hit(p, &all_wires[..], view_proj, bounds) .and_then(|s| Scene::handle_from_wire_name(s)); self.tabs[i].scene.set_hover_highlight(hovered); } else { @@ -2620,7 +2620,7 @@ impl OpenCADStudio { p } else if needs_entity { let hover_handle = - scene::hit_test::click_hit(p, &all_wires[..], view_proj, bounds) + scene::pick::hit_test::click_hit(p, &all_wires[..], view_proj, bounds) .and_then(|s| Scene::handle_from_wire_name(s)) .unwrap_or(acadrust::Handle::NULL); let mut p = self.tabs[i] @@ -3185,7 +3185,7 @@ impl OpenCADStudio { { let vp_mat2 = self.tabs[i].scene.camera.borrow().view_proj(bounds); let all_wires2 = self.tabs[i].scene.hit_test_wires(); - let hit = scene::hit_test::click_hit(p, &all_wires2[..], vp_mat2, bounds) + let hit = scene::pick::hit_test::click_hit(p, &all_wires2[..], vp_mat2, bounds) .and_then(|s| Scene::handle_from_wire_name(s)); if let Some(handle) = hit { // Some commands (e.g. SS_CATCHMENT) need the entity @@ -3374,7 +3374,7 @@ impl OpenCADStudio { let crossing = box_crossing; let all_wires = self.tabs[i].scene.hit_test_wires(); let vp_mat = self.tabs[i].scene.camera.borrow().view_proj(bounds); - let mut handles: Vec = scene::hit_test::box_hit( + let mut handles: Vec = scene::pick::hit_test::box_hit( a, p, crossing, @@ -3385,7 +3385,7 @@ impl OpenCADStudio { .into_iter() .filter_map(|s| Scene::handle_from_wire_name(s)) .collect(); - handles.extend(scene::hit_test::box_hit_hatch( + handles.extend(scene::pick::hit_test::box_hit_hatch( a, p, crossing, @@ -3427,7 +3427,7 @@ impl OpenCADStudio { self.tabs[i].scene.selection.borrow_mut().poly_last_crossing = crossing; let all_wires = self.tabs[i].scene.hit_test_wires(); let vp_mat = self.tabs[i].scene.camera.borrow().view_proj(bounds); - let mut handles: Vec = scene::hit_test::poly_hit( + let mut handles: Vec = scene::pick::hit_test::poly_hit( &poly_pts, crossing, &all_wires[..], @@ -3437,7 +3437,7 @@ impl OpenCADStudio { .into_iter() .filter_map(|s| Scene::handle_from_wire_name(s)) .collect(); - handles.extend(scene::hit_test::poly_hit_hatch( + handles.extend(scene::pick::hit_test::poly_hit_hatch( &poly_pts, crossing, &self.tabs[i].scene.visible_hatches_for_click(), @@ -3481,7 +3481,7 @@ impl OpenCADStudio { // unchanged when off. let mut handled_by_cycling = false; if self.selection_cycling { - let cands: Vec = scene::hit_test::click_hits_all( + let cands: Vec = scene::pick::hit_test::click_hits_all( p, &all_wires[..], vp_mat, @@ -3500,10 +3500,10 @@ impl OpenCADStudio { if !handled_by_cycling { let hit = - scene::hit_test::click_hit(p, &all_wires[..], vp_mat, bounds) + scene::pick::hit_test::click_hit(p, &all_wires[..], vp_mat, bounds) .and_then(|s| Scene::handle_from_wire_name(s)) .or_else(|| { - scene::hit_test::click_hit_hatch( + scene::pick::hit_test::click_hit_hatch( p, &self.tabs[i].scene.visible_hatches_for_click(), vp_mat, @@ -3513,7 +3513,7 @@ impl OpenCADStudio { .or_else(|| { // Block-internal hatch: resolve to the // parent Insert (AutoCAD behaviour). - scene::hit_test::click_hit_insert_hatch( + scene::pick::hit_test::click_hit_insert_hatch( p, &self.tabs[i].scene.insert_hatches_for_click(), vp_mat, @@ -3561,7 +3561,7 @@ impl OpenCADStudio { let crossing = box_crossing; let all_wires = self.tabs[i].scene.hit_test_wires(); let vp_mat = self.tabs[i].scene.camera.borrow().view_proj(bounds); - let mut handles: Vec = scene::hit_test::box_hit( + let mut handles: Vec = scene::pick::hit_test::box_hit( a, p, crossing, @@ -3572,7 +3572,7 @@ impl OpenCADStudio { .into_iter() .filter_map(|s| Scene::handle_from_wire_name(s)) .collect(); - handles.extend(scene::hit_test::box_hit_hatch( + handles.extend(scene::pick::hit_test::box_hit_hatch( a, p, crossing, @@ -3657,7 +3657,7 @@ impl OpenCADStudio { }; let vp_mat = self.tabs[i].scene.camera.borrow().view_proj(bounds); let all_wires = self.tabs[i].scene.hit_test_wires(); - let hit = scene::hit_test::click_hit(p, &all_wires[..], vp_mat, bounds) + let hit = scene::pick::hit_test::click_hit(p, &all_wires[..], vp_mat, bounds) .and_then(|s| Scene::handle_from_wire_name(s)); if let Some(handle) = hit { // Any text-bearing entity opens its in-place editor @@ -3712,7 +3712,7 @@ impl OpenCADStudio { let hit_vp: Option = { let vp_mat = self.tabs[i].scene.camera.borrow().view_proj(bounds); let all_wires = self.tabs[i].scene.hit_test_wires(); - scene::hit_test::click_hit(p, &all_wires[..], vp_mat, bounds) + scene::pick::hit_test::click_hit(p, &all_wires[..], vp_mat, bounds) .and_then(|s| Scene::handle_from_wire_name(s)) .and_then(|h| { if let Some(AcadEntityType::Viewport(vp)) = @@ -3981,7 +3981,7 @@ impl OpenCADStudio { return Task::none(); }; use crate::entities::traits::EntityTypeOps; - use crate::scene::object::GripMenuAction; + use crate::scene::model::object::GripMenuAction; if matches!( item.action, GripMenuAction::Stretch @@ -4643,7 +4643,7 @@ impl OpenCADStudio { self.push_undo_snapshot(i, "CHPROP"); for handle in handles { if let Some(entity) = self.tabs[i].scene.document.get_entity_mut(handle) { - crate::scene::dispatch::apply_common_prop(entity, "layer", &layer); + crate::scene::view::dispatch::apply_common_prop(entity, "layer", &layer); } } self.tabs[i].dirty = true; @@ -4669,7 +4669,7 @@ impl OpenCADStudio { self.push_undo_snapshot(i, "CHPROP"); for handle in handles { if let Some(entity) = self.tabs[i].scene.document.get_entity_mut(handle) { - crate::scene::dispatch::apply_color(entity, color); + crate::scene::view::dispatch::apply_color(entity, color); } } self.tabs[i].dirty = true; @@ -4706,7 +4706,7 @@ impl OpenCADStudio { self.push_undo_snapshot(i, "CHPROP"); for handle in handles { if let Some(entity) = self.tabs[i].scene.document.get_entity_mut(handle) { - crate::scene::dispatch::apply_common_prop(entity, "linetype", <); + crate::scene::view::dispatch::apply_common_prop(entity, "linetype", <); } } self.tabs[i].dirty = true; @@ -4728,7 +4728,7 @@ impl OpenCADStudio { self.push_undo_snapshot(i, "CHPROP"); for handle in handles { if let Some(entity) = self.tabs[i].scene.document.get_entity_mut(handle) { - crate::scene::dispatch::apply_line_weight(entity, lw); + crate::scene::view::dispatch::apply_line_weight(entity, lw); } } self.tabs[i].dirty = true; @@ -4790,7 +4790,7 @@ impl OpenCADStudio { self.push_undo_snapshot(i, "CHPROP"); for &handle in &handles { if let Some(entity) = self.tabs[i].scene.document.get_entity_mut(handle) { - crate::scene::dispatch::apply_common_prop(entity, "layer", &layer); + crate::scene::view::dispatch::apply_common_prop(entity, "layer", &layer); } } self.invalidate_property_targets(i, &handles); @@ -4807,7 +4807,7 @@ impl OpenCADStudio { self.push_undo_snapshot(i, "CHPROP"); for &handle in &handles { if let Some(entity) = self.tabs[i].scene.document.get_entity_mut(handle) { - crate::scene::dispatch::apply_color(entity, color); + crate::scene::view::dispatch::apply_color(entity, color); } } self.invalidate_property_targets(i, &handles); @@ -4826,7 +4826,7 @@ impl OpenCADStudio { self.push_undo_snapshot(i, "CHPROP"); for &handle in &handles { if let Some(entity) = self.tabs[i].scene.document.get_entity_mut(handle) { - crate::scene::dispatch::apply_line_weight(entity, lw); + crate::scene::view::dispatch::apply_line_weight(entity, lw); } } self.invalidate_property_targets(i, &handles); @@ -4843,7 +4843,7 @@ impl OpenCADStudio { self.push_undo_snapshot(i, "CHPROP"); for &handle in &handles { if let Some(entity) = self.tabs[i].scene.document.get_entity_mut(handle) { - crate::scene::dispatch::apply_common_prop(entity, "linetype", <); + crate::scene::view::dispatch::apply_common_prop(entity, "linetype", <); } } self.invalidate_property_targets(i, &handles); @@ -4857,7 +4857,7 @@ impl OpenCADStudio { let i = self.active_tab; let handles = self.property_target_handles(i); if !handles.is_empty() { - use crate::scene::hatch_patterns; + use crate::scene::model::hatch_patterns; if let Some(entry) = hatch_patterns::find(&name) { self.push_undo_snapshot(i, "HATCHEDIT"); for &handle in &handles { @@ -4867,7 +4867,7 @@ impl OpenCADStudio { dxf.pattern = hatch_patterns::build_dxf_pattern(entry); dxf.is_solid = matches!( entry.gpu, - crate::scene::hatch_model::HatchPattern::Solid + crate::scene::model::hatch_model::HatchPattern::Solid ); } if let Some(model) = self.tabs[i].scene.hatches.get_mut(&handle) { @@ -4891,9 +4891,9 @@ impl OpenCADStudio { for &handle in &handles { if let Some(entity) = self.tabs[i].scene.document.get_entity_mut(handle) { match field { - "invisible" => crate::scene::dispatch::toggle_invisible(entity), + "invisible" => crate::scene::view::dispatch::toggle_invisible(entity), _ => { - crate::scene::dispatch::apply_geom_prop(entity, field, "toggle") + crate::scene::view::dispatch::apply_geom_prop(entity, field, "toggle") } } } @@ -4958,7 +4958,7 @@ impl OpenCADStudio { for &handle in &handles { if let Some(entity) = self.tabs[i].scene.document.get_entity_mut(handle) { - crate::scene::dispatch::apply_geom_prop(entity, field, &value); + crate::scene::view::dispatch::apply_geom_prop(entity, field, &value); } } } @@ -5014,12 +5014,12 @@ impl OpenCADStudio { { match field { "linetype_scale" | "transparency" => { - crate::scene::dispatch::apply_common_prop( + crate::scene::view::dispatch::apply_common_prop( entity, field, &val, ); } _ => { - crate::scene::dispatch::apply_geom_prop( + crate::scene::view::dispatch::apply_geom_prop( entity, field, &val, ); } diff --git a/src/app/view.rs b/src/app/view.rs index 1bd761003..753393405 100644 --- a/src/app/view.rs +++ b/src/app/view.rs @@ -3,8 +3,8 @@ use super::document::{DynComponent, DynFieldEntry}; use super::helpers::grid_plane_from_camera; use super::history::history_dropdown_labels; use super::{Message, OpenCADStudio}; -use crate::scene::grip::{grips_to_screen, grips_to_screen_paper}; -use crate::scene::viewport_pane::ViewportPane; +use crate::scene::pick::grip::{grips_to_screen, grips_to_screen_paper}; +use crate::scene::view::viewport_pane::ViewportPane; use crate::scene::{VIEWCUBE_DRAW_PX, VIEWCUBE_PAD}; use crate::ui::overlay; use iced::widget::{ diff --git a/src/app/visibility.rs b/src/app/visibility.rs index 4cc5ff026..9236a4dc1 100644 --- a/src/app/visibility.rs +++ b/src/app/visibility.rs @@ -15,7 +15,7 @@ use acadrust::objects::BlockVisibilityParameter; use acadrust::types::Vector3; use acadrust::{EntityType, Handle}; -use crate::scene::object::{GripDef, GripShape}; +use crate::scene::model::object::{GripDef, GripShape}; use super::OpenCADStudio; diff --git a/src/command/mod.rs b/src/command/mod.rs index 8abb119ce..bb7766ef1 100644 --- a/src/command/mod.rs +++ b/src/command/mod.rs @@ -5,8 +5,8 @@ // viewport events from main.rs and returns `CmdResult` tokens that tell // the host what to do next. -use crate::scene::hatch_model::HatchModel; -use crate::scene::wire_model::WireModel; +use crate::scene::model::hatch_model::HatchModel; +use crate::scene::model::wire_model::WireModel; use crate::scene::Scene; use acadrust::{EntityType, Handle}; use glam::Vec3; @@ -194,7 +194,7 @@ pub enum CmdResult { /// Create a Solid3D placeholder entity + associated MeshModel. /// `mesh_fn` is called with the entity's handle string to build the mesh. CommitSolid3D { - mesh_fn: Box Option + Send>, + mesh_fn: Box Option + Send>, }, /// Extrude the profile entity `handle` by `height` along Z. ExtrudeEntity { diff --git a/src/entities/arc.rs b/src/entities/arc.rs index 56fcdc34d..fd1bac1ea 100644 --- a/src/entities/arc.rs +++ b/src/entities/arc.rs @@ -5,9 +5,9 @@ use truck_modeling::{builder, Point3}; use crate::command::EntityTransform; use crate::entities::common::{center_grip, edit_prop as edit, parse_f64, square_grip}; use crate::entities::traits::TruckConvertible; -use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; -use crate::scene::object::{GripApply, GripDef, PropSection}; -use crate::scene::wire_model::{SnapHint, TangentGeom}; +use crate::scene::convert::acad_to_truck::{TruckEntity, TruckObject}; +use crate::scene::model::object::{GripApply, GripDef, PropSection}; +use crate::scene::model::wire_model::{SnapHint, TangentGeom}; const TAU: f64 = std::f64::consts::TAU; @@ -21,13 +21,13 @@ fn to_truck(arc: &Arc) -> TruckEntity { let normal = (arc.normal.x, arc.normal.y, arc.normal.z); // Compute OCS basis vectors for this entity's normal. - let (ax, ay) = crate::scene::transform::ocs_axes(normal); + let (ax, ay) = crate::scene::view::transform::ocs_axes(normal); let ccw_end = if ea >= sa { ea } else { ea + TAU }; let mid_a = sa + (ccw_end - sa) * 0.5; // Arc centre in WCS. - let (cwx, cwy, cwz) = crate::scene::transform::ocs_point_to_wcs((cx, cy, cz), normal); + let (cwx, cwy, cwz) = crate::scene::view::transform::ocs_point_to_wcs((cx, cy, cz), normal); // Arc points in WCS: centre_wcs + r*cos(a)*Ax + r*sin(a)*Ay let arc_pt = |a: f64| { @@ -198,8 +198,8 @@ fn apply_grip(arc: &mut Arc, grip_id: usize, apply: GripApply) { } fn apply_transform(arc: &mut Arc, t: &EntityTransform) { - crate::scene::transform::apply_standard_entity_transform(arc, t, |entity, p1, p2| { - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::apply_standard_entity_transform(arc, t, |entity, p1, p2| { + crate::scene::view::transform::reflect_xy_point( &mut entity.center.x, &mut entity.center.y, p1, @@ -227,8 +227,8 @@ impl crate::entities::traits::Grippable for Arc { fn apply_grip(&mut self, grip_id: usize, apply: GripApply) { apply_grip(self, grip_id, apply); } - fn grip_menu(&self, grip_id: usize) -> Vec { - use crate::scene::object::{GripMenuAction, GripMenuItem}; + fn grip_menu(&self, grip_id: usize) -> Vec { + use crate::scene::model::object::{GripMenuAction, GripMenuItem}; match grip_id { 0 => vec![GripMenuItem { label: "Stretch", @@ -260,7 +260,7 @@ impl crate::entities::traits::Grippable for Arc { ], } } - fn apply_grip_menu(&mut self, _grip_id: usize, _action: crate::scene::object::GripMenuAction) { + fn apply_grip_menu(&mut self, _grip_id: usize, _action: crate::scene::model::object::GripMenuAction) { // Radius / Arc Length / Lengthen all need a follow-up prompt; // the actual edit happens in `apply_grip_menu_value`. } @@ -268,9 +268,9 @@ impl crate::entities::traits::Grippable for Arc { fn grip_menu_value_prompt( &self, _grip_id: usize, - action: crate::scene::object::GripMenuAction, + action: crate::scene::model::object::GripMenuAction, ) -> Option<&'static str> { - use crate::scene::object::GripMenuAction as A; + use crate::scene::model::object::GripMenuAction as A; match action { A::Radius => Some("New radius"), A::ArcLength => Some("New arc length"), @@ -282,10 +282,10 @@ impl crate::entities::traits::Grippable for Arc { fn apply_grip_menu_value( &mut self, grip_id: usize, - action: crate::scene::object::GripMenuAction, + action: crate::scene::model::object::GripMenuAction, value: f64, ) { - use crate::scene::object::GripMenuAction as A; + use crate::scene::model::object::GripMenuAction as A; match action { A::Radius if value > 0.0 => self.radius = value, A::ArcLength if value > 0.0 && self.radius > 1e-9 => { diff --git a/src/entities/attribute.rs b/src/entities/attribute.rs index 118ce60c4..692998835 100644 --- a/src/entities/attribute.rs +++ b/src/entities/attribute.rs @@ -12,10 +12,11 @@ use crate::entities::text_support::{ MTextRenderOpts, MTextVAnchor, ResolvedTextStyle, }; use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible}; -use crate::scene::acad_to_truck::{TextStroke, TruckEntity, TruckObject}; -use crate::scene::object::{GripApply, GripDef, PropSection, PropValue, Property}; -use crate::scene::wire_model::SnapHint; -use crate::scene::{lff, transform}; +use crate::scene::convert::acad_to_truck::{TextStroke, TruckEntity, TruckObject}; +use crate::scene::model::object::{GripApply, GripDef, PropSection, PropValue, Property}; +use crate::scene::model::wire_model::SnapHint; +use crate::scene::text::lff; +use crate::scene::view::transform; // ── Shared helpers ──────────────────────────────────────────────────────────── diff --git a/src/entities/circle.rs b/src/entities/circle.rs index b9a0fb496..426bd0c62 100644 --- a/src/entities/circle.rs +++ b/src/entities/circle.rs @@ -7,9 +7,9 @@ use crate::entities::common::{ center_grip, edit_prop as edit, parse_f64, ro_prop as ro, square_grip, }; use crate::entities::traits::TruckConvertible; -use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; -use crate::scene::object::{GripApply, GripDef, PropSection}; -use crate::scene::wire_model::{SnapHint, TangentGeom}; +use crate::scene::convert::acad_to_truck::{TruckEntity, TruckObject}; +use crate::scene::model::object::{GripApply, GripDef, PropSection}; +use crate::scene::model::wire_model::{SnapHint, TangentGeom}; fn to_truck(circle: &Circle) -> TruckEntity { let cx = circle.center.x; @@ -18,8 +18,8 @@ fn to_truck(circle: &Circle) -> TruckEntity { let r = circle.radius; let normal = (circle.normal.x, circle.normal.y, circle.normal.z); - let (ax, ay) = crate::scene::transform::ocs_axes(normal); - let (cwx, cwy, cwz) = crate::scene::transform::ocs_point_to_wcs((cx, cy, cz), normal); + let (ax, ay) = crate::scene::view::transform::ocs_axes(normal); + let (cwx, cwy, cwz) = crate::scene::view::transform::ocs_point_to_wcs((cx, cy, cz), normal); // Circle points in WCS: centre_wcs ± r * Ax and centre_wcs ± r * Ay let pt = |da: (f64, f64, f64), db: (f64, f64, f64), s: f64| { @@ -182,8 +182,8 @@ fn apply_grip(circle: &mut Circle, grip_id: usize, apply: GripApply) { } fn apply_transform(circle: &mut Circle, t: &EntityTransform) { - crate::scene::transform::apply_standard_entity_transform(circle, t, |entity, p1, p2| { - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::apply_standard_entity_transform(circle, t, |entity, p1, p2| { + crate::scene::view::transform::reflect_xy_point( &mut entity.center.x, &mut entity.center.y, p1, diff --git a/src/entities/common.rs b/src/entities/common.rs index 283aa75ac..adb63a81e 100644 --- a/src/entities/common.rs +++ b/src/entities/common.rs @@ -1,6 +1,6 @@ use std::cell::Cell; -use crate::scene::object::{GripDef, GripShape, PropValue, Property}; +use crate::scene::model::object::{GripDef, GripShape, PropValue, Property}; /// Linear / angular unit format pulled from the document header so the /// per-thread properties pipeline can format values consistently without diff --git a/src/entities/dimension.rs b/src/entities/dimension.rs index 4fe5a3d4c..e561882ec 100644 --- a/src/entities/dimension.rs +++ b/src/entities/dimension.rs @@ -10,26 +10,26 @@ use crate::entities::common::{ center_grip, edit_prop as edit, parse_f64, ro_prop as ro, square_grip, }; use crate::entities::traits::{Grippable, PropertyEditable, Transformable}; -use crate::scene::object::{GripApply, GripDef, PropSection}; +use crate::scene::model::object::{GripApply, GripDef, PropSection}; -fn base_props(base: &DimensionBase) -> Vec { +fn base_props(base: &DimensionBase) -> Vec { vec![ - crate::scene::object::Property { + crate::scene::model::object::Property { label: "Text".into(), field: "text", - value: crate::scene::object::PropValue::EditText(base.text.clone()), + value: crate::scene::model::object::PropValue::EditText(base.text.clone()), }, - crate::scene::object::Property { + crate::scene::model::object::Property { label: "User Text".into(), field: "user_text", - value: crate::scene::object::PropValue::EditText( + value: crate::scene::model::object::PropValue::EditText( base.user_text.clone().unwrap_or_default(), ), }, - crate::scene::object::Property { + crate::scene::model::object::Property { label: "Style".into(), field: "style_name", - value: crate::scene::object::PropValue::EditText(base.style_name.clone()), + value: crate::scene::model::object::PropValue::EditText(base.style_name.clone()), }, edit("Text X", "text_x", base.text_middle_point.x), edit("Text Y", "text_y", base.text_middle_point.y), @@ -135,7 +135,7 @@ fn linear_like_props( first: acadrust::types::Vector3, second: acadrust::types::Vector3, definition: acadrust::types::Vector3, -) -> Vec { +) -> Vec { vec![ edit("First X", "first_x", first.x), edit("First Y", "first_y", first.y), @@ -152,7 +152,7 @@ fn linear_like_props( fn radius_like_props( center: acadrust::types::Vector3, point: acadrust::types::Vector3, -) -> Vec { +) -> Vec { vec![ edit("Center X", "center_x", center.x), edit("Center Y", "center_y", center.y), @@ -168,7 +168,7 @@ fn angular_props( first: acadrust::types::Vector3, second: acadrust::types::Vector3, definition: acadrust::types::Vector3, -) -> Vec { +) -> Vec { vec![ edit("Vertex X", "vertex_x", vertex.x), edit("Vertex Y", "vertex_y", vertex.y), @@ -555,7 +555,7 @@ fn scale_point(p: &mut acadrust::types::Vector3, center: Vec3, factor: f32) { } fn mirror_point(p: &mut acadrust::types::Vector3, p1: Vec3, p2: Vec3) { - crate::scene::transform::reflect_xy_point(&mut p.x, &mut p.y, p1, p2); + crate::scene::view::transform::reflect_xy_point(&mut p.x, &mut p.y, p1, p2); } impl PropertyEditable for Dimension { @@ -713,8 +713,8 @@ impl Grippable for Dimension { self.base_mut().actual_measurement = self.measurement(); } - fn grip_menu(&self, grip_id: usize) -> Vec { - use crate::scene::object::{GripMenuAction, GripMenuItem}; + fn grip_menu(&self, grip_id: usize) -> Vec { + use crate::scene::model::object::{GripMenuAction, GripMenuItem}; let (dim_line_grip, text_grip) = match self { Dimension::Linear(_) | Dimension::Aligned(_) => (2, 3), Dimension::Radius(_) | Dimension::Diameter(_) => (1, 2), @@ -775,8 +775,8 @@ impl Grippable for Dimension { } } - fn apply_grip_menu(&mut self, grip_id: usize, action: crate::scene::object::GripMenuAction) { - use crate::scene::object::GripMenuAction as A; + fn apply_grip_menu(&mut self, grip_id: usize, action: crate::scene::model::object::GripMenuAction) { + use crate::scene::model::object::GripMenuAction as A; let (_dim_line_grip, text_grip) = match self { Dimension::Linear(_) | Dimension::Aligned(_) => (2, 3), Dimension::Radius(_) | Dimension::Diameter(_) => (1, 2), @@ -827,18 +827,18 @@ impl Grippable for Dimension { // definition. Shared dim machinery (`ArrowKind`, `DimGeom`, `append_arrow`, // arrow blocks, colour resolution, `add_segment` / `add_polyline`, // `normalized_or`, `entity_z`, `offset_snap_pts`) lives in -// `scene::tessellate` and is reused by Leader / MultiLeader too. +// `scene::convert::tessellate` and is reused by Leader / MultiLeader too. use acadrust::entities::{MText, Text}; use acadrust::tables::DimStyle; use acadrust::types::{Color as AcadColor, Vector3}; use acadrust::{CadDocument, EntityType, Handle}; -use crate::scene::tess_util::aci_to_rgba; -use crate::scene::tessellate::{ +use crate::scene::convert::tess_util::aci_to_rgba; +use crate::scene::convert::tessellate::{ add_polyline, add_segment, append_arrow, arrow_from_block, normalized_or, ArrowKind, DimGeom, }; -use crate::scene::wire_model::{SnapHint, WireModel}; +use crate::scene::model::wire_model::{SnapHint, WireModel}; pub trait DimensionTess { fn tessellate( @@ -1338,7 +1338,7 @@ fn resolve_pattern_by_handle( .find(|lt| lt.handle == handle) .map(|lt| lt.name.clone()); match name { - Some(n) => crate::scene::render::resolve_pattern(&doc.line_types, &n, scale), + Some(n) => crate::scene::view::render::resolve_pattern(&doc.line_types, &n, scale), None => (0.0, [0.0; 8]), } } diff --git a/src/entities/ellipse.rs b/src/entities/ellipse.rs index 75217d361..b6e80cb8e 100644 --- a/src/entities/ellipse.rs +++ b/src/entities/ellipse.rs @@ -5,9 +5,9 @@ use truck_modeling::{builder, BSplineCurve, Curve, Edge, KnotVec, Point3, Wire}; use crate::command::EntityTransform; use crate::entities::common::{center_grip, edit_prop as edit, ro_prop as ro, square_grip}; use crate::entities::traits::TruckConvertible; -use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; -use crate::scene::object::{GripApply, GripDef, PropSection}; -use crate::scene::wire_model::SnapHint; +use crate::scene::convert::acad_to_truck::{TruckEntity, TruckObject}; +use crate::scene::model::object::{GripApply, GripDef, PropSection}; +use crate::scene::model::wire_model::SnapHint; const TAU: f64 = std::f64::consts::TAU; @@ -218,14 +218,14 @@ fn apply_grip(ell: &mut Ellipse, grip_id: usize, apply: GripApply) { } fn apply_transform(ell: &mut Ellipse, t: &EntityTransform) { - crate::scene::transform::apply_standard_entity_transform(ell, t, |entity, p1, p2| { - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::apply_standard_entity_transform(ell, t, |entity, p1, p2| { + crate::scene::view::transform::reflect_xy_point( &mut entity.center.x, &mut entity.center.y, p1, p2, ); - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::reflect_xy_point( &mut entity.major_axis.x, &mut entity.major_axis.y, p1, diff --git a/src/entities/hatch.rs b/src/entities/hatch.rs index a99da8674..d9683535a 100644 --- a/src/entities/hatch.rs +++ b/src/entities/hatch.rs @@ -4,9 +4,9 @@ use glam::Vec3; use crate::command::EntityTransform; use crate::entities::common::{center_grip, edit_prop as edit, parse_f64, ro_prop as ro}; use crate::entities::traits::{FallbackTess, Grippable, PropertyEditable, Transformable}; -use crate::scene::object::{GripApply, GripDef, PropSection, PropValue, Property}; -use crate::scene::tess_util::{arc_segments, arc_signed_span, wire_chord_tol, FallbackGeometry}; -use crate::scene::wire_model::SnapHint; +use crate::scene::model::object::{GripApply, GripDef, PropSection, PropValue, Property}; +use crate::scene::convert::tess_util::{arc_segments, arc_signed_span, wire_chord_tol, FallbackGeometry}; +use crate::scene::model::wire_model::SnapHint; fn properties(h: &Hatch) -> PropSection { let pattern_type = match h.pattern_type { @@ -89,7 +89,7 @@ fn apply_geom_prop(h: &mut Hatch, field: &str, value: &str) { } fn apply_transform(h: &mut Hatch, t: &EntityTransform) { - crate::scene::transform::apply_standard_entity_transform(h, t, |entity, p1, p2| { + crate::scene::view::transform::apply_standard_entity_transform(h, t, |entity, p1, p2| { // Delegate the mirror to acadrust's transform_hatch (via the Entity // trait): it flips the boundary-arc direction flags, re-mirrors the // stored angles and preserves the stored sweep — including the @@ -97,7 +97,7 @@ fn apply_transform(h: &mut Hatch, t: &EntityTransform) { // hand-rolled angle-swap here was only valid for ccw boundary arcs on // an axis-aligned mirror line and went stale the moment those // conventions were fixed upstream. - let t = crate::scene::transform::reflection_about_xy_line(p1, p2); + let t = crate::scene::view::transform::reflection_about_xy_line(p1, p2); acadrust::entities::Entity::apply_transform(entity, &t); }); } @@ -282,8 +282,8 @@ impl Grippable for Hatch { } } - fn grip_menu(&self, _grip_id: usize) -> Vec { - use crate::scene::object::{GripMenuAction, GripMenuItem}; + fn grip_menu(&self, _grip_id: usize) -> Vec { + use crate::scene::model::object::{GripMenuAction, GripMenuItem}; vec![ GripMenuItem { label: "Stretch", @@ -304,7 +304,7 @@ impl Grippable for Hatch { ] } - fn apply_grip_menu(&mut self, _grip_id: usize, _action: crate::scene::object::GripMenuAction) { + fn apply_grip_menu(&mut self, _grip_id: usize, _action: crate::scene::model::object::GripMenuAction) { // Origin / Angle / Scale need a follow-up value — handled by // `apply_grip_menu_value`. } @@ -312,9 +312,9 @@ impl Grippable for Hatch { fn grip_menu_value_prompt( &self, _grip_id: usize, - action: crate::scene::object::GripMenuAction, + action: crate::scene::model::object::GripMenuAction, ) -> Option<&'static str> { - use crate::scene::object::GripMenuAction as A; + use crate::scene::model::object::GripMenuAction as A; match action { A::HatchAngle => Some("Angle (deg)"), A::HatchScale => Some("Scale"), @@ -325,10 +325,10 @@ impl Grippable for Hatch { fn apply_grip_menu_value( &mut self, _grip_id: usize, - action: crate::scene::object::GripMenuAction, + action: crate::scene::model::object::GripMenuAction, value: f64, ) { - use crate::scene::object::GripMenuAction as A; + use crate::scene::model::object::GripMenuAction as A; match action { A::HatchAngle => { self.pattern_angle = value.to_radians(); @@ -350,7 +350,7 @@ impl FallbackTess for Hatch { // Convert a 2D OCS hatch boundary point to WCS, then subtract world_offset. let to_wcs = |x: f64, y: f64| -> [f32; 3] { let (wx, wy, wz) = - crate::scene::transform::ocs_point_to_wcs((x, y, self.elevation), normal); + crate::scene::view::transform::ocs_point_to_wcs((x, y, self.elevation), normal); [(wx - ox) as f32, (wy - oy) as f32, (wz - oz) as f32] }; let mut pts: Vec<[f32; 3]> = Vec::new(); diff --git a/src/entities/insert.rs b/src/entities/insert.rs index 93526d987..1d6989cc3 100644 --- a/src/entities/insert.rs +++ b/src/entities/insert.rs @@ -6,9 +6,11 @@ use glam::Vec3; use crate::command::EntityTransform; use crate::entities::common::{edit_prop as edit, parse_f64, ro_prop as ro, square_grip}; -use crate::scene::object::{GripApply, GripDef, PropSection}; -use crate::scene::wire_model::WireModel; -use crate::scene::{block_cache, render, tessellate}; +use crate::scene::model::object::{GripApply, GripDef, PropSection}; +use crate::scene::model::wire_model::WireModel; +use crate::scene::cache::block_cache; +use crate::scene::convert::tessellate; +use crate::scene::view::render; fn grips(ins: &Insert) -> Vec { let p = glam::DVec3::new(ins.insert_point.x, ins.insert_point.y, ins.insert_point.z); @@ -63,7 +65,7 @@ fn apply_grip(ins: &mut Insert, _grip_id: usize, apply: GripApply) { } fn apply_transform(ins: &mut Insert, t: &EntityTransform) { - crate::scene::transform::apply_standard_entity_transform(ins, t, |entity, p1, p2| { + crate::scene::view::transform::apply_standard_entity_transform(ins, t, |entity, p1, p2| { let dx = (p2.x - p1.x) as f64; let dy = (p2.y - p1.y) as f64; let len = (dx * dx + dy * dy).sqrt(); @@ -98,7 +100,7 @@ impl crate::entities::traits::FallbackTess for Insert { fn fallback_geometry( &self, world_offset: [f64; 3], - ) -> crate::scene::tess_util::FallbackGeometry { + ) -> crate::scene::convert::tess_util::FallbackGeometry { let [ox, oy, oz] = world_offset; let ip = Vec3::new( (self.insert_point.x - ox) as f32, @@ -114,7 +116,7 @@ impl crate::entities::traits::FallbackTess for Insert { ]; ( pts, - vec![(ip, crate::scene::wire_model::SnapHint::Insertion)], + vec![(ip, crate::scene::model::wire_model::SnapHint::Insertion)], vec![], vec![], ) diff --git a/src/entities/leader.rs b/src/entities/leader.rs index 96d484600..dbe88f2a9 100644 --- a/src/entities/leader.rs +++ b/src/entities/leader.rs @@ -5,9 +5,9 @@ use glam::Vec3; use crate::command::EntityTransform; use crate::entities::common::{center_grip, edit_prop as edit, ro_prop as ro, square_grip}; use crate::entities::traits::TruckConvertible; -use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; -use crate::scene::object::{GripApply, GripDef, PropSection, PropValue, Property}; -use crate::scene::wire_model::TangentGeom; +use crate::scene::convert::acad_to_truck::{TruckEntity, TruckObject}; +use crate::scene::model::object::{GripApply, GripDef, PropSection, PropValue, Property}; +use crate::scene::model::wire_model::TangentGeom; // ── TruckConvertible (used for snap/grip key-vertices) ───────────────────── @@ -428,17 +428,17 @@ fn apply_geom_prop(leader: &mut Leader, field: &str, value: &str) { // ── Transform ────────────────────────────────────────────────────────────── fn apply_transform(leader: &mut Leader, t: &EntityTransform) { - crate::scene::transform::apply_standard_entity_transform(leader, t, |entity, p1, p2| { + crate::scene::view::transform::apply_standard_entity_transform(leader, t, |entity, p1, p2| { for v in &mut entity.vertices { - crate::scene::transform::reflect_xy_point(&mut v.x, &mut v.y, p1, p2); + crate::scene::view::transform::reflect_xy_point(&mut v.x, &mut v.y, p1, p2); } - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::reflect_xy_point( &mut entity.block_offset.x, &mut entity.block_offset.y, p1, p2, ); - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::reflect_xy_point( &mut entity.annotation_offset.x, &mut entity.annotation_offset.y, p1, @@ -465,8 +465,8 @@ impl crate::entities::traits::Grippable for Leader { fn apply_grip(&mut self, grip_id: usize, apply: GripApply) { apply_grip(self, grip_id, apply); } - fn grip_menu(&self, grip_id: usize) -> Vec { - use crate::scene::object::{GripMenuAction, GripMenuItem}; + fn grip_menu(&self, grip_id: usize) -> Vec { + use crate::scene::model::object::{GripMenuAction, GripMenuItem}; let n = self.vertices.len(); if grip_id == 0 { // Arrow head — stretch only. @@ -497,8 +497,8 @@ impl crate::entities::traits::Grippable for Leader { }] } } - fn apply_grip_menu(&mut self, grip_id: usize, action: crate::scene::object::GripMenuAction) { - use crate::scene::object::GripMenuAction as A; + fn apply_grip_menu(&mut self, grip_id: usize, action: crate::scene::model::object::GripMenuAction) { + use crate::scene::model::object::GripMenuAction as A; let n = self.vertices.len(); match action { A::AddVertex if grip_id < n => { @@ -540,7 +540,7 @@ impl crate::entities::traits::Transformable for Leader { /// Per-entity tessellation entry for `Leader`. Lives here so all leader /// tess code stays alongside the entity definition. Cross-entity dim -/// machinery (arrow shapes, `DimGeom`) lives in `scene::tessellate` and +/// machinery (arrow shapes, `DimGeom`) lives in `scene::convert::tessellate` and /// is reused via the dim arrow emitter so the leader matches the active /// DIMSTYLE. pub trait LeaderTess { @@ -553,7 +553,7 @@ pub trait LeaderTess { line_weight_px: f32, world_offset: [f64; 3], anno_scale: f32, - ) -> crate::scene::wire_model::WireModel; + ) -> crate::scene::model::wire_model::WireModel; } impl LeaderTess for Leader { @@ -566,9 +566,9 @@ impl LeaderTess for Leader { line_weight_px: f32, world_offset: [f64; 3], anno_scale: f32, - ) -> crate::scene::wire_model::WireModel { - use crate::scene::tessellate::{append_arrow, arrow_from_block, ArrowKind, DimGeom}; - use crate::scene::wire_model::WireModel; + ) -> crate::scene::model::wire_model::WireModel { + use crate::scene::convert::tessellate::{append_arrow, arrow_from_block, ArrowKind, DimGeom}; + use crate::scene::model::wire_model::WireModel; let color = if selected { WireModel::SELECTED } else { diff --git a/src/entities/line.rs b/src/entities/line.rs index 0c9fba4a8..f9a9af98d 100644 --- a/src/entities/line.rs +++ b/src/entities/line.rs @@ -6,18 +6,18 @@ use crate::entities::common::{ center_grip, edit_prop as edit, parse_f64, ro_prop as ro, square_grip, }; use crate::entities::traits::TruckConvertible; -use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; -use crate::scene::object::{GripApply, GripDef, PropSection}; -use crate::scene::wire_model::TangentGeom; +use crate::scene::convert::acad_to_truck::{TruckEntity, TruckObject}; +use crate::scene::model::object::{GripApply, GripDef, PropSection}; +use crate::scene::model::wire_model::TangentGeom; fn to_truck(line: &Line) -> TruckEntity { let normal = (line.normal.x, line.normal.y, line.normal.z); - let (sx, sy, sz) = crate::scene::transform::ocs_point_to_wcs( + let (sx, sy, sz) = crate::scene::view::transform::ocs_point_to_wcs( (line.start.x, line.start.y, line.start.z), normal, ); let (ex, ey, ez) = - crate::scene::transform::ocs_point_to_wcs((line.end.x, line.end.y, line.end.z), normal); + crate::scene::view::transform::ocs_point_to_wcs((line.end.x, line.end.y, line.end.z), normal); let p0 = Point3::new(sx, sy, sz); let p1 = Point3::new(ex, ey, ez); let kv: Vec<[f64; 3]> = vec![[p0.x, p0.y, p0.z], [p1.x, p1.y, p1.z]]; @@ -134,13 +134,13 @@ fn apply_transform(line: &mut Line, t: &EntityTransform) { )); } EntityTransform::Rotate { center, angle_rad } => { - crate::scene::transform::apply_standard_transform(line, *center, *angle_rad); + crate::scene::view::transform::apply_standard_transform(line, *center, *angle_rad); } EntityTransform::Scale { center, factor } => { - crate::scene::transform::apply_standard_scale(line, *center, *factor); + crate::scene::view::transform::apply_standard_scale(line, *center, *factor); } EntityTransform::Mirror { p1, p2 } => { - crate::scene::transform::mirror_xy_line(line, *p1, *p2); + crate::scene::view::transform::mirror_xy_line(line, *p1, *p2); } } } @@ -158,8 +158,8 @@ impl crate::entities::traits::Grippable for Line { fn apply_grip(&mut self, grip_id: usize, apply: GripApply) { apply_grip(self, grip_id, apply); } - fn grip_menu(&self, grip_id: usize) -> Vec { - use crate::scene::object::{GripMenuAction, GripMenuItem}; + fn grip_menu(&self, grip_id: usize) -> Vec { + use crate::scene::model::object::{GripMenuAction, GripMenuItem}; if grip_id == 2 { vec![GripMenuItem { label: "Stretch", @@ -178,7 +178,7 @@ impl crate::entities::traits::Grippable for Line { ] } } - fn apply_grip_menu(&mut self, _grip_id: usize, _action: crate::scene::object::GripMenuAction) { + fn apply_grip_menu(&mut self, _grip_id: usize, _action: crate::scene::model::object::GripMenuAction) { // Lengthen needs a follow-up distance — handled by // `apply_grip_menu_value`. } @@ -186,9 +186,9 @@ impl crate::entities::traits::Grippable for Line { fn grip_menu_value_prompt( &self, _grip_id: usize, - action: crate::scene::object::GripMenuAction, + action: crate::scene::model::object::GripMenuAction, ) -> Option<&'static str> { - use crate::scene::object::GripMenuAction as A; + use crate::scene::model::object::GripMenuAction as A; match action { A::Lengthen => Some("Distance"), _ => None, @@ -198,10 +198,10 @@ impl crate::entities::traits::Grippable for Line { fn apply_grip_menu_value( &mut self, grip_id: usize, - action: crate::scene::object::GripMenuAction, + action: crate::scene::model::object::GripMenuAction, value: f64, ) { - use crate::scene::object::GripMenuAction as A; + use crate::scene::model::object::GripMenuAction as A; if !matches!(action, A::Lengthen) { return; } diff --git a/src/entities/lwpolyline.rs b/src/entities/lwpolyline.rs index c9cc0d386..d1d89d367 100644 --- a/src/entities/lwpolyline.rs +++ b/src/entities/lwpolyline.rs @@ -6,9 +6,9 @@ use crate::entities::common::{ edit_prop as edit, parse_f64, rectangle_grip, ro_prop as ro, square_grip, }; use crate::entities::traits::TruckConvertible; -use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; -use crate::scene::object::{GripApply, GripDef, PropSection}; -use crate::scene::wire_model::TangentGeom; +use crate::scene::convert::acad_to_truck::{TruckEntity, TruckObject}; +use crate::scene::model::object::{GripApply, GripDef, PropSection}; +use crate::scene::model::wire_model::TangentGeom; const TAU: f64 = std::f64::consts::TAU; @@ -120,7 +120,7 @@ fn to_truck(pline: &LwPolyline) -> TruckEntity { // Convert OCS (x, y, elevation) to WCS Point3. let to_wcs = |x: f64, y: f64| -> (f64, f64, f64) { - crate::scene::transform::ocs_point_to_wcs((x, y, elev), normal) + crate::scene::view::transform::ocs_point_to_wcs((x, y, elev), normal) }; let to_pt = |v: &LwVertex| -> Point3 { let (wx, wy, wz) = to_wcs(v.location.x, v.location.y); @@ -418,9 +418,9 @@ fn apply_grip(pline: &mut LwPolyline, grip_id: usize, apply: GripApply) { } fn apply_transform(pline: &mut LwPolyline, t: &EntityTransform) { - crate::scene::transform::apply_standard_entity_transform(pline, t, |entity, p1, p2| { + crate::scene::view::transform::apply_standard_entity_transform(pline, t, |entity, p1, p2| { for v in &mut entity.vertices { - crate::scene::transform::reflect_xy_point(&mut v.location.x, &mut v.location.y, p1, p2); + crate::scene::view::transform::reflect_xy_point(&mut v.location.x, &mut v.location.y, p1, p2); // Bulge encodes which side the arc bows to; a reflection // reverses it or every curved segment flips to the wrong side. v.bulge = -v.bulge; @@ -435,14 +435,14 @@ impl TruckConvertible for LwPolyline { } impl crate::entities::traits::Grippable for LwPolyline { - fn grips(&self) -> Vec { + fn grips(&self) -> Vec { grips(self) } - fn apply_grip(&mut self, grip_id: usize, apply: crate::scene::object::GripApply) { + fn apply_grip(&mut self, grip_id: usize, apply: crate::scene::model::object::GripApply) { apply_grip(self, grip_id, apply); } - fn grip_menu(&self, grip_id: usize) -> Vec { - use crate::scene::object::{GripMenuAction, GripMenuItem}; + fn grip_menu(&self, grip_id: usize) -> Vec { + use crate::scene::model::object::{GripMenuAction, GripMenuItem}; let n = self.vertices.len(); if grip_id < n { // Vertex grip. @@ -490,8 +490,8 @@ impl crate::entities::traits::Grippable for LwPolyline { convert, ] } - fn apply_grip_menu(&mut self, grip_id: usize, action: crate::scene::object::GripMenuAction) { - use crate::scene::object::GripMenuAction as A; + fn apply_grip_menu(&mut self, grip_id: usize, action: crate::scene::model::object::GripMenuAction) { + use crate::scene::model::object::GripMenuAction as A; let n = self.vertices.len(); match action { A::Stretch => {} @@ -546,7 +546,7 @@ impl crate::entities::traits::PropertyEditable for LwPolyline { fn geometry_properties( &self, _text_style_names: &[String], - ) -> crate::scene::object::PropSection { + ) -> crate::scene::model::object::PropSection { properties(self) } fn apply_geom_prop(&mut self, field: &str, value: &str) { diff --git a/src/entities/mesh.rs b/src/entities/mesh.rs index 687f988cf..fbcb552ac 100644 --- a/src/entities/mesh.rs +++ b/src/entities/mesh.rs @@ -4,9 +4,9 @@ use glam::Vec3; use crate::command::EntityTransform; use crate::entities::common::{ro_prop as ro, square_grip}; use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible}; -use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; -use crate::scene::object::{GripApply, GripDef, PropSection}; -use crate::scene::wire_model::SnapHint; +use crate::scene::convert::acad_to_truck::{TruckEntity, TruckObject}; +use crate::scene::model::object::{GripApply, GripDef, PropSection}; +use crate::scene::model::wire_model::SnapHint; // ── Face3D ──────────────────────────────────────────────────────────────────── @@ -160,14 +160,14 @@ impl PropertyEditable for Face3D { impl Transformable for Face3D { fn apply_transform(&mut self, t: &EntityTransform) { - crate::scene::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { + crate::scene::view::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { for corner in [ &mut entity.first_corner, &mut entity.second_corner, &mut entity.third_corner, &mut entity.fourth_corner, ] { - crate::scene::transform::reflect_xy_point(&mut corner.x, &mut corner.y, p1, p2); + crate::scene::view::transform::reflect_xy_point(&mut corner.x, &mut corner.y, p1, p2); } }); } @@ -322,9 +322,9 @@ impl PropertyEditable for PolygonMesh { impl Transformable for PolygonMesh { fn apply_transform(&mut self, t: &EntityTransform) { - crate::scene::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { + crate::scene::view::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { for v in &mut entity.vertices { - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::reflect_xy_point( &mut v.location.x, &mut v.location.y, p1, @@ -472,9 +472,9 @@ impl PropertyEditable for PolyfaceMesh { impl Transformable for PolyfaceMesh { fn apply_transform(&mut self, t: &EntityTransform) { - crate::scene::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { + crate::scene::view::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { for v in &mut entity.vertices { - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::reflect_xy_point( &mut v.location.x, &mut v.location.y, p1, @@ -631,9 +631,9 @@ impl PropertyEditable for Mesh { impl Transformable for Mesh { fn apply_transform(&mut self, t: &EntityTransform) { - crate::scene::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { + crate::scene::view::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { for v in &mut entity.vertices { - crate::scene::transform::reflect_xy_point(&mut v.x, &mut v.y, p1, p2); + crate::scene::view::transform::reflect_xy_point(&mut v.x, &mut v.y, p1, p2); } }); } diff --git a/src/entities/mline.rs b/src/entities/mline.rs index a6919e49a..f5fa428b6 100644 --- a/src/entities/mline.rs +++ b/src/entities/mline.rs @@ -4,9 +4,9 @@ use glam::Vec3; use crate::command::EntityTransform; use crate::entities::common::{edit_prop as edit, ro_prop as ro, square_grip}; use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible}; -use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; -use crate::scene::object::{GripApply, GripDef, PropSection, PropValue, Property}; -use crate::scene::wire_model::SnapHint; +use crate::scene::convert::acad_to_truck::{TruckEntity, TruckObject}; +use crate::scene::model::object::{GripApply, GripDef, PropSection, PropValue, Property}; +use crate::scene::model::wire_model::SnapHint; impl TruckConvertible for MLine { fn to_truck(&self, _document: &acadrust::CadDocument) -> Option { @@ -149,8 +149,8 @@ impl Grippable for MLine { } } - fn grip_menu(&self, _grip_id: usize) -> Vec { - use crate::scene::object::{GripMenuAction, GripMenuItem}; + fn grip_menu(&self, _grip_id: usize) -> Vec { + use crate::scene::model::object::{GripMenuAction, GripMenuItem}; vec![ GripMenuItem { label: "Stretch", @@ -167,8 +167,8 @@ impl Grippable for MLine { ] } - fn apply_grip_menu(&mut self, grip_id: usize, action: crate::scene::object::GripMenuAction) { - use crate::scene::object::GripMenuAction as A; + fn apply_grip_menu(&mut self, grip_id: usize, action: crate::scene::model::object::GripMenuAction) { + use crate::scene::model::object::GripMenuAction as A; let n = self.vertices.len(); match action { A::AddVertex if grip_id < n => { @@ -274,16 +274,16 @@ impl PropertyEditable for MLine { impl Transformable for MLine { fn apply_transform(&mut self, t: &EntityTransform) { - crate::scene::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { + crate::scene::view::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { for v in &mut entity.vertices { - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::reflect_xy_point( &mut v.position.x, &mut v.position.y, p1, p2, ); } - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::reflect_xy_point( &mut entity.start_point.x, &mut entity.start_point.y, p1, diff --git a/src/entities/mtext.rs b/src/entities/mtext.rs index 482e35168..5083b026a 100644 --- a/src/entities/mtext.rs +++ b/src/entities/mtext.rs @@ -7,9 +7,9 @@ use crate::entities::text_support::{ layout_mtext, resolve_text_style, GlyphBox, MTextRenderOpts, MTextVAnchor, }; use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible}; -use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; -use crate::scene::object::{GripApply, GripDef, PropSection, PropValue, Property}; -use crate::scene::wire_model::SnapHint; +use crate::scene::convert::acad_to_truck::{TruckEntity, TruckObject}; +use crate::scene::model::object::{GripApply, GripDef, PropSection, PropValue, Property}; +use crate::scene::model::wire_model::SnapHint; fn attachment_str(a: &AttachmentPoint) -> &'static str { match a { @@ -327,8 +327,8 @@ fn apply_grip(t: &mut MText, grip_id: usize, apply: GripApply) { } fn apply_transform(t: &mut MText, tr: &EntityTransform) { - crate::scene::transform::apply_standard_entity_transform(t, tr, |entity, p1, p2| { - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::apply_standard_entity_transform(t, tr, |entity, p1, p2| { + crate::scene::view::transform::reflect_xy_point( &mut entity.insertion_point.x, &mut entity.insertion_point.y, p1, @@ -356,8 +356,8 @@ impl Grippable for MText { apply_grip(self, grip_id, apply); } - fn grip_menu(&self, grip_id: usize) -> Vec { - use crate::scene::object::{GripMenuAction, GripMenuItem}; + fn grip_menu(&self, grip_id: usize) -> Vec { + use crate::scene::model::object::{GripMenuAction, GripMenuItem}; if grip_id == 0 { // Insertion point vec![ @@ -383,7 +383,7 @@ impl Grippable for MText { } } - fn apply_grip_menu(&mut self, _grip_id: usize, _action: crate::scene::object::GripMenuAction) { + fn apply_grip_menu(&mut self, _grip_id: usize, _action: crate::scene::model::object::GripMenuAction) { // Rotate needs a follow-up angle handled by // `apply_grip_menu_value`; Move-with-Text is the default drag. } @@ -391,9 +391,9 @@ impl Grippable for MText { fn grip_menu_value_prompt( &self, _grip_id: usize, - action: crate::scene::object::GripMenuAction, + action: crate::scene::model::object::GripMenuAction, ) -> Option<&'static str> { - use crate::scene::object::GripMenuAction as A; + use crate::scene::model::object::GripMenuAction as A; match action { A::RotateText => Some("Rotation (deg)"), _ => None, @@ -403,10 +403,10 @@ impl Grippable for MText { fn apply_grip_menu_value( &mut self, _grip_id: usize, - action: crate::scene::object::GripMenuAction, + action: crate::scene::model::object::GripMenuAction, value: f64, ) { - use crate::scene::object::GripMenuAction as A; + use crate::scene::model::object::GripMenuAction as A; if matches!(action, A::RotateText) { self.rotation = value.to_radians(); } diff --git a/src/entities/multileader.rs b/src/entities/multileader.rs index 8dd3ed202..e2aeaecea 100644 --- a/src/entities/multileader.rs +++ b/src/entities/multileader.rs @@ -31,9 +31,9 @@ use crate::entities::common::{ center_grip, edit_prop as edit, ro_prop as ro, square_grip, triangle_grip, }; use crate::entities::traits::TruckConvertible; -use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; -use crate::scene::object::{GripApply, GripDef, PropSection, PropValue, Property}; -use crate::scene::wire_model::{SnapHint, TangentGeom}; +use crate::scene::convert::acad_to_truck::{TruckEntity, TruckObject}; +use crate::scene::model::object::{GripApply, GripDef, PropSection, PropValue, Property}; +use crate::scene::model::wire_model::{SnapHint, TangentGeom}; // ── TruckConvertible ──────────────────────────────────────────────────────── @@ -840,7 +840,7 @@ fn parse_attachment(s: &str) -> TextAttachmentType { // ── Transform ────────────────────────────────────────────────────────────── fn apply_transform(ml: &mut MultiLeader, t: &EntityTransform) { - crate::scene::transform::apply_standard_entity_transform(ml, t, |entity, p1, p2| { + crate::scene::view::transform::apply_standard_entity_transform(ml, t, |entity, p1, p2| { // Reflect every point on the leader (line points, connection points, // break-point endpoints) AND every direction vector that drives the // text orientation. Without the direction reflection text would keep @@ -848,16 +848,16 @@ fn apply_transform(ml: &mut MultiLeader, t: &EntityTransform) { for root in &mut entity.context.leader_roots { for line in &mut root.lines { for p in &mut line.points { - crate::scene::transform::reflect_xy_point(&mut p.x, &mut p.y, p1, p2); + crate::scene::view::transform::reflect_xy_point(&mut p.x, &mut p.y, p1, p2); } for bp in &mut line.break_points { - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::reflect_xy_point( &mut bp.start_point.x, &mut bp.start_point.y, p1, p2, ); - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::reflect_xy_point( &mut bp.end_point.x, &mut bp.end_point.y, p1, @@ -865,7 +865,7 @@ fn apply_transform(ml: &mut MultiLeader, t: &EntityTransform) { ); } } - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::reflect_xy_point( &mut root.connection_point.x, &mut root.connection_point.y, p1, @@ -873,13 +873,13 @@ fn apply_transform(ml: &mut MultiLeader, t: &EntityTransform) { ); reflect_xy_direction(&mut root.direction.x, &mut root.direction.y, p1, p2); for bp in &mut root.break_points { - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::reflect_xy_point( &mut bp.start_point.x, &mut bp.start_point.y, p1, p2, ); - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::reflect_xy_point( &mut bp.end_point.x, &mut bp.end_point.y, p1, @@ -887,7 +887,7 @@ fn apply_transform(ml: &mut MultiLeader, t: &EntityTransform) { ); } } - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::reflect_xy_point( &mut entity.context.text_location.x, &mut entity.context.text_location.y, p1, @@ -916,7 +916,7 @@ fn reflect_xy_direction(dx: &mut f64, dy: &mut f64, p1: Vec3, p2: Vec3) { let p2_rel = Vec3::new(p2.x - p1.x, p2.y - p1.y, 0.0); let mut tip_x = *dx; let mut tip_y = *dy; - crate::scene::transform::reflect_xy_point(&mut tip_x, &mut tip_y, zero, p2_rel); + crate::scene::view::transform::reflect_xy_point(&mut tip_x, &mut tip_y, zero, p2_rel); *dx = tip_x; *dy = tip_y; } @@ -936,8 +936,8 @@ impl crate::entities::traits::Grippable for MultiLeader { fn apply_grip(&mut self, grip_id: usize, apply: GripApply) { apply_grip(self, grip_id, apply); } - fn grip_menu(&self, grip_id: usize) -> Vec { - use crate::scene::object::{GripMenuAction, GripMenuItem}; + fn grip_menu(&self, grip_id: usize) -> Vec { + use crate::scene::model::object::{GripMenuAction, GripMenuItem}; let n_vertices: usize = self .context .leader_roots @@ -984,8 +984,8 @@ impl crate::entities::traits::Grippable for MultiLeader { ] } } - fn apply_grip_menu(&mut self, grip_id: usize, action: crate::scene::object::GripMenuAction) { - use crate::scene::object::GripMenuAction as A; + fn apply_grip_menu(&mut self, grip_id: usize, action: crate::scene::model::object::GripMenuAction) { + use crate::scene::model::object::GripMenuAction as A; // Locate the (root, line) and vertex position owning this grip id. let mut idx = 0usize; let mut loc: Option<(usize, usize, acadrust::types::Vector3)> = None; @@ -1063,7 +1063,7 @@ pub trait MultiLeaderTess { world_offset: [f64; 3], anno_scale: f32, world_per_pixel: Option, - ) -> Vec; + ) -> Vec; } impl MultiLeaderTess for MultiLeader { @@ -1077,11 +1077,11 @@ impl MultiLeaderTess for MultiLeader { world_offset: [f64; 3], anno_scale: f32, world_per_pixel: Option, - ) -> Vec { - use crate::scene::tessellate::{ + ) -> Vec { + use crate::scene::convert::tessellate::{ append_arrow, arrow_from_block, color_or_inherit, tessellate, ArrowKind, DimGeom, }; - use crate::scene::wire_model::{SnapHint, TangentGeom, WireModel}; + use crate::scene::model::wire_model::{SnapHint, TangentGeom, WireModel}; use glam::Vec3; let ml = self; // line_color falls back to the entity colour when the MultiLeader's own @@ -1110,7 +1110,7 @@ impl MultiLeaderTess for MultiLeader { .map(|lt| lt.name.clone()); match name { Some(n) => { - crate::scene::render::resolve_pattern(&document.line_types, &n, lt_scale) + crate::scene::view::render::resolve_pattern(&document.line_types, &n, lt_scale) } None => (0.0, [0.0; 8]), } diff --git a/src/entities/ole2frame.rs b/src/entities/ole2frame.rs index 2b1d75213..078f431de 100644 --- a/src/entities/ole2frame.rs +++ b/src/entities/ole2frame.rs @@ -4,9 +4,9 @@ use glam::Vec3; use crate::command::EntityTransform; use crate::entities::common::{center_grip, edit_prop as edit, ro_prop as ro, square_grip}; use crate::entities::traits::TruckConvertible; -use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; -use crate::scene::object::{GripApply, GripDef, PropSection}; -use crate::scene::wire_model::SnapHint; +use crate::scene::convert::acad_to_truck::{TruckEntity, TruckObject}; +use crate::scene::model::object::{GripApply, GripDef, PropSection}; +use crate::scene::model::wire_model::SnapHint; fn to_truck(ole: &Ole2Frame) -> TruckEntity { let x0 = ole.upper_left_corner.x; @@ -184,7 +184,7 @@ impl crate::entities::traits::FallbackTess for Ole2Frame { fn fallback_geometry( &self, world_offset: [f64; 3], - ) -> crate::scene::tess_util::FallbackGeometry { + ) -> crate::scene::convert::tess_util::FallbackGeometry { // OLE objects carry a bounding rectangle in model space. // Render a simple X-through-rectangle placeholder. let [ox, oy, oz] = world_offset; diff --git a/src/entities/point.rs b/src/entities/point.rs index c9ca95f16..159fd4276 100644 --- a/src/entities/point.rs +++ b/src/entities/point.rs @@ -5,9 +5,9 @@ use truck_modeling::{builder, Point3}; use crate::command::EntityTransform; use crate::entities::common::{edit_prop as edit, parse_f64, square_grip}; use crate::entities::traits::TruckConvertible; -use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; -use crate::scene::object::{GripApply, GripDef, PropSection}; -use crate::scene::wire_model::SnapHint; +use crate::scene::convert::acad_to_truck::{TruckEntity, TruckObject}; +use crate::scene::model::object::{GripApply, GripDef, PropSection}; +use crate::scene::model::wire_model::SnapHint; /// Resolve PDSIZE (negative = % of viewport, 0 = 5% default, positive = world). /// We don't know the viewport height at tessellation time, so percentages and @@ -93,7 +93,7 @@ fn point_glyph(cx: f64, cy: f64, z: f64, pdmode: i16, pdsize: f64) -> Vec<[f64; fn to_truck(pt: &Point, document: &acadrust::CadDocument) -> TruckEntity { let normal = (pt.normal.x, pt.normal.y, pt.normal.z); - let (wx, wy, wz) = crate::scene::transform::ocs_point_to_wcs( + let (wx, wy, wz) = crate::scene::view::transform::ocs_point_to_wcs( (pt.location.x, pt.location.y, pt.location.z), normal, ); @@ -175,8 +175,8 @@ fn apply_grip(pt: &mut Point, _grip_id: usize, apply: GripApply) { } fn apply_transform(pt: &mut Point, t: &EntityTransform) { - crate::scene::transform::apply_standard_entity_transform(pt, t, |entity, p1, p2| { - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::apply_standard_entity_transform(pt, t, |entity, p1, p2| { + crate::scene::view::transform::reflect_xy_point( &mut entity.location.x, &mut entity.location.y, p1, diff --git a/src/entities/polyline.rs b/src/entities/polyline.rs index 4115ca6f3..3452f2711 100644 --- a/src/entities/polyline.rs +++ b/src/entities/polyline.rs @@ -4,9 +4,9 @@ use truck_modeling::{builder, Edge, Point3, Wire}; use crate::command::EntityTransform; use crate::entities::common::{edit_prop as edit, ro_prop as ro, square_grip}; use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible}; -use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; -use crate::scene::object::{GripApply, GripDef, PropSection, PropValue, Property}; -use crate::scene::wire_model::TangentGeom; +use crate::scene::convert::acad_to_truck::{TruckEntity, TruckObject}; +use crate::scene::model::object::{GripApply, GripDef, PropSection, PropValue, Property}; +use crate::scene::model::wire_model::TangentGeom; // ── Polyline (old-style 3D heavy polyline) ──────────────────────────────────── @@ -69,8 +69,8 @@ impl Grippable for Polyline { } } - fn grip_menu(&self, _grip_id: usize) -> Vec { - use crate::scene::object::{GripMenuAction, GripMenuItem}; + fn grip_menu(&self, _grip_id: usize) -> Vec { + use crate::scene::model::object::{GripMenuAction, GripMenuItem}; vec![ GripMenuItem { label: "Stretch", @@ -87,8 +87,8 @@ impl Grippable for Polyline { ] } - fn apply_grip_menu(&mut self, grip_id: usize, action: crate::scene::object::GripMenuAction) { - use crate::scene::object::GripMenuAction as A; + fn apply_grip_menu(&mut self, grip_id: usize, action: crate::scene::model::object::GripMenuAction) { + use crate::scene::model::object::GripMenuAction as A; let n = self.vertices.len(); match action { A::AddVertex if grip_id < n => { @@ -148,9 +148,9 @@ impl PropertyEditable for Polyline { impl Transformable for Polyline { fn apply_transform(&mut self, t: &EntityTransform) { - crate::scene::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { + crate::scene::view::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { for v in &mut entity.vertices { - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::reflect_xy_point( &mut v.location.x, &mut v.location.y, p1, @@ -184,7 +184,7 @@ fn tessellate_polyline2d(pl: &Polyline2D) -> TruckEntity { let mut key_verts: Vec<[f64; 3]> = Vec::new(); let to_wcs = |x: f64, y: f64| -> (f64, f64, f64) { - crate::scene::transform::ocs_point_to_wcs((x, y, elev), normal) + crate::scene::view::transform::ocs_point_to_wcs((x, y, elev), normal) }; let to_pt = |v: &acadrust::entities::Vertex2D| -> Point3 { let (wx, wy, wz) = to_wcs(v.location.x, v.location.y); @@ -338,8 +338,8 @@ impl Grippable for Polyline2D { } } - fn grip_menu(&self, _grip_id: usize) -> Vec { - use crate::scene::object::{GripMenuAction, GripMenuItem}; + fn grip_menu(&self, _grip_id: usize) -> Vec { + use crate::scene::model::object::{GripMenuAction, GripMenuItem}; vec![ GripMenuItem { label: "Stretch", @@ -356,8 +356,8 @@ impl Grippable for Polyline2D { ] } - fn apply_grip_menu(&mut self, grip_id: usize, action: crate::scene::object::GripMenuAction) { - use crate::scene::object::GripMenuAction as A; + fn apply_grip_menu(&mut self, grip_id: usize, action: crate::scene::model::object::GripMenuAction) { + use crate::scene::model::object::GripMenuAction as A; let n = self.vertices.len(); let elev = self.elevation; match action { @@ -467,9 +467,9 @@ impl PropertyEditable for Polyline2D { impl Transformable for Polyline2D { fn apply_transform(&mut self, t: &EntityTransform) { - crate::scene::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { + crate::scene::view::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { for v in &mut entity.vertices { - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::reflect_xy_point( &mut v.location.x, &mut v.location.y, p1, @@ -556,8 +556,8 @@ impl Grippable for Polyline3D { } } - fn grip_menu(&self, _grip_id: usize) -> Vec { - use crate::scene::object::{GripMenuAction, GripMenuItem}; + fn grip_menu(&self, _grip_id: usize) -> Vec { + use crate::scene::model::object::{GripMenuAction, GripMenuItem}; vec![ GripMenuItem { label: "Stretch", @@ -574,8 +574,8 @@ impl Grippable for Polyline3D { ] } - fn apply_grip_menu(&mut self, grip_id: usize, action: crate::scene::object::GripMenuAction) { - use crate::scene::object::GripMenuAction as A; + fn apply_grip_menu(&mut self, grip_id: usize, action: crate::scene::model::object::GripMenuAction) { + use crate::scene::model::object::GripMenuAction as A; let n = self.vertices.len(); match action { A::AddVertex if grip_id < n => { @@ -669,9 +669,9 @@ impl PropertyEditable for Polyline3D { impl Transformable for Polyline3D { fn apply_transform(&mut self, t: &EntityTransform) { - crate::scene::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { + crate::scene::view::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { for v in &mut entity.vertices { - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::reflect_xy_point( &mut v.position.x, &mut v.position.y, p1, diff --git a/src/entities/raster_image.rs b/src/entities/raster_image.rs index d96616840..0e774b355 100644 --- a/src/entities/raster_image.rs +++ b/src/entities/raster_image.rs @@ -3,8 +3,8 @@ use acadrust::entities::{RasterImage, Wipeout}; use crate::command::EntityTransform; use crate::entities::common::{center_grip, edit_prop as edit, ro_prop as ro, square_grip}; use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible}; -use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; -use crate::scene::object::{GripApply, GripDef, PropSection, PropValue, Property}; +use crate::scene::convert::acad_to_truck::{TruckEntity, TruckObject}; +use crate::scene::model::object::{GripApply, GripDef, PropSection, PropValue, Property}; // ── Shared geometry helpers ─────────────────────────────────────────────────── @@ -235,8 +235,8 @@ impl PropertyEditable for RasterImage { impl Transformable for RasterImage { fn apply_transform(&mut self, t: &EntityTransform) { - crate::scene::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { + crate::scene::view::transform::reflect_xy_point( &mut entity.insertion_point.x, &mut entity.insertion_point.y, p1, @@ -496,8 +496,8 @@ impl PropertyEditable for Wipeout { impl Transformable for Wipeout { fn apply_transform(&mut self, t: &EntityTransform) { - crate::scene::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { + crate::scene::view::transform::reflect_xy_point( &mut entity.insertion_point.x, &mut entity.insertion_point.y, p1, diff --git a/src/entities/ray.rs b/src/entities/ray.rs index de39a02d2..b9306cff6 100644 --- a/src/entities/ray.rs +++ b/src/entities/ray.rs @@ -3,8 +3,8 @@ use acadrust::entities::{Ray, XLine}; use crate::command::EntityTransform; use crate::entities::common::{center_grip, edit_prop as edit, square_grip}; use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible}; -use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; -use crate::scene::object::{GripApply, GripDef, PropSection}; +use crate::scene::convert::acad_to_truck::{TruckEntity, TruckObject}; +use crate::scene::model::object::{GripApply, GripDef, PropSection}; /// Display length used when rendering semi-infinite / infinite lines. const DISPLAY_EXTENT: f64 = 1_000_000.0; @@ -126,8 +126,8 @@ impl PropertyEditable for Ray { impl Transformable for Ray { fn apply_transform(&mut self, t: &EntityTransform) { - crate::scene::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { + crate::scene::view::transform::reflect_xy_point( &mut entity.base_point.x, &mut entity.base_point.y, p1, @@ -263,8 +263,8 @@ impl PropertyEditable for XLine { impl Transformable for XLine { fn apply_transform(&mut self, t: &EntityTransform) { - crate::scene::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { + crate::scene::view::transform::reflect_xy_point( &mut entity.base_point.x, &mut entity.base_point.y, p1, diff --git a/src/entities/shape.rs b/src/entities/shape.rs index 11085242f..9d504c8d9 100644 --- a/src/entities/shape.rs +++ b/src/entities/shape.rs @@ -11,10 +11,10 @@ use glam::Vec3; use crate::command::EntityTransform; use crate::entities::common::{edit_prop as edit, ro_prop as ro, square_grip}; use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible}; -use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; -use crate::scene::object::{GripApply, GripDef, PropSection}; -use crate::scene::transform; -use crate::scene::wire_model::SnapHint; +use crate::scene::convert::acad_to_truck::{TruckEntity, TruckObject}; +use crate::scene::model::object::{GripApply, GripDef, PropSection}; +use crate::scene::view::transform; +use crate::scene::model::wire_model::SnapHint; // ── Marker geometry ─────────────────────────────────────────────────────────── diff --git a/src/entities/solid.rs b/src/entities/solid.rs index 74e7a66e3..48d97230e 100644 --- a/src/entities/solid.rs +++ b/src/entities/solid.rs @@ -10,9 +10,9 @@ use glam::Vec3; use crate::command::EntityTransform; use crate::entities::common::{edit_prop as edit, square_grip}; use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible}; -use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; -use crate::scene::object::{GripApply, GripDef, PropSection}; -use crate::scene::wire_model::SnapHint; +use crate::scene::convert::acad_to_truck::{TruckEntity, TruckObject}; +use crate::scene::model::object::{GripApply, GripDef, PropSection}; +use crate::scene::model::wire_model::SnapHint; fn v3(v: &acadrust::types::Vector3) -> [f64; 3] { [v.x, v.y, v.z] @@ -147,14 +147,14 @@ impl PropertyEditable for Solid { impl Transformable for Solid { fn apply_transform(&mut self, t: &EntityTransform) { - crate::scene::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { + crate::scene::view::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { for corner in [ &mut entity.first_corner, &mut entity.second_corner, &mut entity.third_corner, &mut entity.fourth_corner, ] { - crate::scene::transform::reflect_xy_point(&mut corner.x, &mut corner.y, p1, p2); + crate::scene::view::transform::reflect_xy_point(&mut corner.x, &mut corner.y, p1, p2); } }); } diff --git a/src/entities/solid3d.rs b/src/entities/solid3d.rs index c875acab6..1a97cdb28 100644 --- a/src/entities/solid3d.rs +++ b/src/entities/solid3d.rs @@ -11,7 +11,7 @@ use glam::Vec3; use crate::entities::common::{center_grip, ro_prop as ro}; use crate::entities::traits::{Grippable, PropertyEditable}; -use crate::scene::object::{GripApply, GripDef, PropSection}; +use crate::scene::model::object::{GripApply, GripDef, PropSection}; // ── shared helpers ──────────────────────────────────────────────────────────── @@ -260,8 +260,8 @@ impl PropertyEditable for Body { // to repeat a three-arm `match entity` block at every callsite — the // helpers below collapse those to a single call. -use crate::scene::mesh_model::MeshLodSet; -use crate::scene::solid3d_tess; +use crate::scene::model::mesh_model::MeshLodSet; +use crate::scene::convert::solid3d_tess; use acadrust::{types::Vector3, EntityType}; /// `point_of_reference` of an ACIS-backed volume entity, if applicable. diff --git a/src/entities/spline.rs b/src/entities/spline.rs index 01b57c0d4..83e529546 100644 --- a/src/entities/spline.rs +++ b/src/entities/spline.rs @@ -7,8 +7,8 @@ use truck_modeling::{ use crate::command::EntityTransform; use crate::entities::common::{ro_prop as ro, square_grip}; use crate::entities::traits::TruckConvertible; -use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; -use crate::scene::object::{GripApply, GripDef, PropSection}; +use crate::scene::convert::acad_to_truck::{TruckEntity, TruckObject}; +use crate::scene::model::object::{GripApply, GripDef, PropSection}; fn to_truck(spl: &Spline) -> TruckEntity { let n = spl.control_points.len(); @@ -141,12 +141,12 @@ fn apply_grip(spline: &mut Spline, grip_id: usize, apply: GripApply) { } fn apply_transform(spline: &mut Spline, t: &EntityTransform) { - crate::scene::transform::apply_standard_entity_transform(spline, t, |entity, p1, p2| { + crate::scene::view::transform::apply_standard_entity_transform(spline, t, |entity, p1, p2| { for cp in &mut entity.control_points { - crate::scene::transform::reflect_xy_point(&mut cp.x, &mut cp.y, p1, p2); + crate::scene::view::transform::reflect_xy_point(&mut cp.x, &mut cp.y, p1, p2); } for fp in &mut entity.fit_points { - crate::scene::transform::reflect_xy_point(&mut fp.x, &mut fp.y, p1, p2); + crate::scene::view::transform::reflect_xy_point(&mut fp.x, &mut fp.y, p1, p2); } }); } @@ -164,8 +164,8 @@ impl crate::entities::traits::Grippable for Spline { fn apply_grip(&mut self, grip_id: usize, apply: GripApply) { apply_grip(self, grip_id, apply); } - fn grip_menu(&self, _grip_id: usize) -> Vec { - use crate::scene::object::{GripMenuAction, GripMenuItem}; + fn grip_menu(&self, _grip_id: usize) -> Vec { + use crate::scene::model::object::{GripMenuAction, GripMenuItem}; vec![ GripMenuItem { label: "Stretch", @@ -185,8 +185,8 @@ impl crate::entities::traits::Grippable for Spline { }, ] } - fn apply_grip_menu(&mut self, grip_id: usize, action: crate::scene::object::GripMenuAction) { - use crate::scene::object::GripMenuAction as A; + fn apply_grip_menu(&mut self, grip_id: usize, action: crate::scene::model::object::GripMenuAction) { + use crate::scene::model::object::GripMenuAction as A; let n = self.control_points.len(); let min_cv = (self.degree as usize).saturating_add(1).max(2); match action { diff --git a/src/entities/table.rs b/src/entities/table.rs index 617992971..7699a413d 100644 --- a/src/entities/table.rs +++ b/src/entities/table.rs @@ -7,10 +7,10 @@ use crate::entities::text_support::{ layout_mtext, MTextRenderOpts, MTextVAnchor, ResolvedTextStyle, }; use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible}; -use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; -use crate::scene::object::{GripApply, GripDef, PropSection}; -use crate::scene::transform; -use crate::scene::wire_model::SnapHint; +use crate::scene::convert::acad_to_truck::{TruckEntity, TruckObject}; +use crate::scene::model::object::{GripApply, GripDef, PropSection}; +use crate::scene::view::transform; +use crate::scene::model::wire_model::SnapHint; fn v3(v: &acadrust::types::Vector3) -> Vec3 { Vec3::new(v.x as f32, v.y as f32, v.z as f32) @@ -335,9 +335,9 @@ pub fn tessellate_table( entity_color: [f32; 4], line_weight_px: f32, world_offset: [f64; 3], -) -> Vec { - use crate::scene::tess_util::aci_to_rgba; - use crate::scene::wire_model::WireModel; +) -> Vec { + use crate::scene::convert::tess_util::aci_to_rgba; + use crate::scene::model::wire_model::WireModel; use acadrust::types::Color; use rustc_hash::FxHashMap as HashMap; diff --git a/src/entities/text.rs b/src/entities/text.rs index 88136b046..d2afc5d26 100644 --- a/src/entities/text.rs +++ b/src/entities/text.rs @@ -7,10 +7,10 @@ use crate::entities::text_support::{ resolve_dxf_special_chars, resolve_text_style, text_local_bounds, }; use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible}; -use crate::scene::acad_to_truck::{TextStroke, TruckEntity, TruckObject}; -use crate::scene::lff; -use crate::scene::object::{GripApply, GripDef, PropSection, PropValue, Property}; -use crate::scene::wire_model::SnapHint; +use crate::scene::convert::acad_to_truck::{TextStroke, TruckEntity, TruckObject}; +use crate::scene::text::lff; +use crate::scene::model::object::{GripApply, GripDef, PropSection, PropValue, Property}; +use crate::scene::model::wire_model::SnapHint; fn text_halign_str(a: &acadrust::entities::TextHorizontalAlignment) -> &'static str { use acadrust::entities::TextHorizontalAlignment::*; @@ -50,7 +50,7 @@ fn sync_text_alignment_point(t: &mut Text) { fn to_truck(t: &Text, document: &acadrust::CadDocument) -> TruckEntity { let normal = (t.normal.x, t.normal.y, t.normal.z); - let (wsx, wsy, wsz) = crate::scene::transform::ocs_point_to_wcs( + let (wsx, wsy, wsz) = crate::scene::view::transform::ocs_point_to_wcs( ( t.insertion_point.x, t.insertion_point.y, @@ -287,15 +287,15 @@ fn apply_grip(t: &mut Text, _grip_id: usize, apply: GripApply) { } fn apply_transform(t: &mut Text, tr: &EntityTransform) { - crate::scene::transform::apply_standard_entity_transform(t, tr, |entity, p1, p2| { - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::apply_standard_entity_transform(t, tr, |entity, p1, p2| { + crate::scene::view::transform::reflect_xy_point( &mut entity.insertion_point.x, &mut entity.insertion_point.y, p1, p2, ); if let Some(ref mut a) = entity.alignment_point { - crate::scene::transform::reflect_xy_point(&mut a.x, &mut a.y, p1, p2); + crate::scene::view::transform::reflect_xy_point(&mut a.x, &mut a.y, p1, p2); } let dx = (p2.x - p1.x) as f64; let dy = (p2.y - p1.y) as f64; @@ -320,8 +320,8 @@ impl Grippable for Text { apply_grip(self, grip_id, apply); } - fn grip_menu(&self, _grip_id: usize) -> Vec { - use crate::scene::object::{GripMenuAction, GripMenuItem}; + fn grip_menu(&self, _grip_id: usize) -> Vec { + use crate::scene::model::object::{GripMenuAction, GripMenuItem}; vec![ GripMenuItem { label: "Stretch", @@ -338,7 +338,7 @@ impl Grippable for Text { ] } - fn apply_grip_menu(&mut self, _grip_id: usize, _action: crate::scene::object::GripMenuAction) { + fn apply_grip_menu(&mut self, _grip_id: usize, _action: crate::scene::model::object::GripMenuAction) { // Move-with-Text falls through to Stretch (single grip moves // the whole text); Rotate needs a follow-up angle handled by // `apply_grip_menu_value`. @@ -347,9 +347,9 @@ impl Grippable for Text { fn grip_menu_value_prompt( &self, _grip_id: usize, - action: crate::scene::object::GripMenuAction, + action: crate::scene::model::object::GripMenuAction, ) -> Option<&'static str> { - use crate::scene::object::GripMenuAction as A; + use crate::scene::model::object::GripMenuAction as A; match action { A::RotateText => Some("Rotation (deg)"), _ => None, @@ -359,10 +359,10 @@ impl Grippable for Text { fn apply_grip_menu_value( &mut self, _grip_id: usize, - action: crate::scene::object::GripMenuAction, + action: crate::scene::model::object::GripMenuAction, value: f64, ) { - use crate::scene::object::GripMenuAction as A; + use crate::scene::model::object::GripMenuAction as A; if matches!(action, A::RotateText) { self.rotation = value.to_radians(); } diff --git a/src/entities/text_support.rs b/src/entities/text_support.rs index c0818de62..0b54453ed 100644 --- a/src/entities/text_support.rs +++ b/src/entities/text_support.rs @@ -1,9 +1,9 @@ use acadrust::types::aci_table::aci_to_rgb; use acadrust::{CadDocument, EntityType}; -use crate::scene::acad_to_truck::TextStroke; -use crate::scene::font_face::Face; -use crate::scene::lff; +use crate::scene::convert::acad_to_truck::TextStroke; +use crate::scene::text::font_face::Face; +use crate::scene::text::lff; pub struct ResolvedTextStyle { pub font_name: String, diff --git a/src/entities/tolerance.rs b/src/entities/tolerance.rs index 205d6fa6c..20fdce7fa 100644 --- a/src/entities/tolerance.rs +++ b/src/entities/tolerance.rs @@ -4,10 +4,11 @@ use glam::Vec3; use crate::command::EntityTransform; use crate::entities::common::{edit_prop as edit, ro_prop as ro, square_grip}; use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible}; -use crate::scene::acad_to_truck::{TextStroke, TruckEntity, TruckObject}; -use crate::scene::object::{GripApply, GripDef, PropSection}; -use crate::scene::wire_model::SnapHint; -use crate::scene::{lff, transform}; +use crate::scene::convert::acad_to_truck::{TextStroke, TruckEntity, TruckObject}; +use crate::scene::model::object::{GripApply, GripDef, PropSection}; +use crate::scene::model::wire_model::SnapHint; +use crate::scene::text::lff; +use crate::scene::view::transform; // ── GDT text parser ─────────────────────────────────────────────────────────── diff --git a/src/entities/traits.rs b/src/entities/traits.rs index c819cf4c2..64c763b70 100644 --- a/src/entities/traits.rs +++ b/src/entities/traits.rs @@ -1,11 +1,11 @@ use acadrust::{CadDocument, EntityType}; use crate::command::EntityTransform; -use crate::scene::acad_to_truck::TruckEntity; -use crate::scene::object::{ +use crate::scene::convert::acad_to_truck::TruckEntity; +use crate::scene::model::object::{ GripApply, GripDef, GripMenuAction, GripMenuItem, PropSection, }; -use crate::scene::tess_util::FallbackGeometry; +use crate::scene::convert::tess_util::FallbackGeometry; pub trait TruckConvertible { fn to_truck(&self, document: &CadDocument) -> Option; @@ -192,13 +192,13 @@ macro_rules! dispatch { macro_rules! impl_entity_basics { ($T:ty) => { impl $crate::entities::traits::Grippable for $T { - fn grips(&self) -> Vec<$crate::scene::object::GripDef> { + fn grips(&self) -> Vec<$crate::scene::model::object::GripDef> { grips(self) } fn apply_grip( &mut self, grip_id: usize, - apply: $crate::scene::object::GripApply, + apply: $crate::scene::model::object::GripApply, ) { apply_grip(self, grip_id, apply); } @@ -207,7 +207,7 @@ macro_rules! impl_entity_basics { fn geometry_properties( &self, _text_style_names: &[String], - ) -> $crate::scene::object::PropSection { + ) -> $crate::scene::model::object::PropSection { properties(self) } fn apply_geom_prop(&mut self, field: &str, value: &str) { @@ -229,13 +229,13 @@ macro_rules! impl_entity_basics { macro_rules! impl_entity_basics_with_text_styles { ($T:ty) => { impl $crate::entities::traits::Grippable for $T { - fn grips(&self) -> Vec<$crate::scene::object::GripDef> { + fn grips(&self) -> Vec<$crate::scene::model::object::GripDef> { grips(self) } fn apply_grip( &mut self, grip_id: usize, - apply: $crate::scene::object::GripApply, + apply: $crate::scene::model::object::GripApply, ) { apply_grip(self, grip_id, apply); } @@ -244,7 +244,7 @@ macro_rules! impl_entity_basics_with_text_styles { fn geometry_properties( &self, text_style_names: &[String], - ) -> $crate::scene::object::PropSection { + ) -> $crate::scene::model::object::PropSection { properties(self, text_style_names) } fn apply_geom_prop(&mut self, field: &str, value: &str) { diff --git a/src/entities/underlay.rs b/src/entities/underlay.rs index 37bb18124..5234c2595 100644 --- a/src/entities/underlay.rs +++ b/src/entities/underlay.rs @@ -10,9 +10,9 @@ use glam::Vec3; use crate::command::EntityTransform; use crate::entities::common::{center_grip, edit_prop as edit, ro_prop as ro, square_grip}; use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible}; -use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; -use crate::scene::object::{GripApply, GripDef, PropSection}; -use crate::scene::wire_model::SnapHint; +use crate::scene::convert::acad_to_truck::{TruckEntity, TruckObject}; +use crate::scene::model::object::{GripApply, GripDef, PropSection}; +use crate::scene::model::wire_model::SnapHint; // ── Helpers ─────────────────────────────────────────────────────────────────── @@ -224,7 +224,7 @@ impl PropertyEditable for Underlay { impl Transformable for Underlay { fn apply_transform(&mut self, t: &EntityTransform) { - use crate::scene::transform::reflect_xy_point; + use crate::scene::view::transform::reflect_xy_point; match t { EntityTransform::Translate(d) => { self.insertion_point.x += d.x as f64; diff --git a/src/entities/viewport.rs b/src/entities/viewport.rs index 592206f37..b072dea43 100644 --- a/src/entities/viewport.rs +++ b/src/entities/viewport.rs @@ -5,7 +5,7 @@ use crate::entities::common::{ center_grip, edit_prop as edit, parse_f64, ro_prop as ro, square_grip, }; -use crate::scene::object::{GripApply, GripDef, PropSection, PropValue, Property}; +use crate::scene::model::object::{GripApply, GripDef, PropSection, PropValue, Property}; // ── Standard scale options ──────────────────────────────────────────────── @@ -533,8 +533,8 @@ fn apply_grip(vp: &mut Viewport, grip_id: usize, apply: GripApply) { } fn apply_transform(vp: &mut Viewport, t: &EntityTransform) { - crate::scene::transform::apply_standard_entity_transform(vp, t, |entity, p1, p2| { - crate::scene::transform::reflect_xy_point( + crate::scene::view::transform::apply_standard_entity_transform(vp, t, |entity, p1, p2| { + crate::scene::view::transform::reflect_xy_point( &mut entity.center.x, &mut entity.center.y, p1, @@ -549,7 +549,7 @@ impl crate::entities::traits::FallbackTess for Viewport { fn fallback_geometry( &self, world_offset: [f64; 3], - ) -> crate::scene::tess_util::FallbackGeometry { + ) -> crate::scene::convert::tess_util::FallbackGeometry { let [ox, oy, oz] = world_offset; let cx = (self.center.x - ox) as f32; let cy = (self.center.y - oy) as f32; diff --git a/src/io/obj.rs b/src/io/obj.rs index 2e09d172c..925c1a32f 100644 --- a/src/io/obj.rs +++ b/src/io/obj.rs @@ -4,7 +4,7 @@ // Quads are split into two triangles. // Only the first object/group is imported (no multi-object support needed). -use crate::scene::mesh_model::MeshModel; +use crate::scene::model::mesh_model::MeshModel; /// Parse OBJ text into a MeshModel. /// Returns `None` if the file has no usable geometry. diff --git a/src/io/pdf_export.rs b/src/io/pdf_export.rs index 823ad80c8..93b457602 100644 --- a/src/io/pdf_export.rs +++ b/src/io/pdf_export.rs @@ -9,7 +9,7 @@ // drawing origin at the paper origin. use crate::io::plot_style::PlotStyleTable; -use crate::scene::hatch_model::{HatchModel, HatchPattern}; +use crate::scene::model::hatch_model::{HatchModel, HatchPattern}; use crate::scene::WireModel; use printpdf::{ Color, Line, LineCapStyle, LineJoinStyle, LinePoint, Mm, Op, PaintMode, PdfDocument, PdfPage, diff --git a/src/io/print_to_printer.rs b/src/io/print_to_printer.rs index 5d0b4026e..4ab4abf15 100644 --- a/src/io/print_to_printer.rs +++ b/src/io/print_to_printer.rs @@ -9,7 +9,7 @@ use crate::io::pdf_export; use crate::io::plot_style::PlotStyleTable; -use crate::scene::hatch_model::HatchModel; +use crate::scene::model::hatch_model::HatchModel; use crate::scene::WireModel; /// Render `wires` (plus hatch / wipeout fills) to a temp PDF and dispatch it diff --git a/src/io/step.rs b/src/io/step.rs index fbf73c391..8846d2c95 100644 --- a/src/io/step.rs +++ b/src/io/step.rs @@ -12,7 +12,7 @@ // This produces larger-than-optimal files but is universally importable by // CAD systems that accept AP203. -use crate::scene::mesh_model::MeshModel; +use crate::scene::model::mesh_model::MeshModel; use std::fmt::Write as FmtWrite; /// Build a STEP AP203 text representation from a slice of mesh models. diff --git a/src/io/stl.rs b/src/io/stl.rs index c34b10e08..99e86d0dd 100644 --- a/src/io/stl.rs +++ b/src/io/stl.rs @@ -11,7 +11,7 @@ use std::io::Write; -use crate::scene::mesh_model::MeshModel; +use crate::scene::model::mesh_model::MeshModel; /// Build a binary STL byte buffer from a slice of mesh models. /// Returns `None` if there are no triangles to export. diff --git a/src/modules/annotate/aligned_dim.rs b/src/modules/annotate/aligned_dim.rs index 60071cb15..6635b8488 100644 --- a/src/modules/annotate/aligned_dim.rs +++ b/src/modules/annotate/aligned_dim.rs @@ -7,7 +7,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_aligned.svg")); diff --git a/src/modules/annotate/angular_dim.rs b/src/modules/annotate/angular_dim.rs index 55b619c1b..dcdb559b7 100644 --- a/src/modules/annotate/angular_dim.rs +++ b/src/modules/annotate/angular_dim.rs @@ -4,7 +4,7 @@ use acadrust::EntityType; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; use glam::Vec3; pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_angular.svg")); diff --git a/src/modules/annotate/diameter_dim.rs b/src/modules/annotate/diameter_dim.rs index 4ea620e9b..ef0021149 100644 --- a/src/modules/annotate/diameter_dim.rs +++ b/src/modules/annotate/diameter_dim.rs @@ -7,7 +7,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_diameter.svg")); diff --git a/src/modules/annotate/dim_baseline.rs b/src/modules/annotate/dim_baseline.rs index 8187428ac..2669193c3 100644 --- a/src/modules/annotate/dim_baseline.rs +++ b/src/modules/annotate/dim_baseline.rs @@ -13,7 +13,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_baseline.svg")); diff --git a/src/modules/annotate/dim_continue.rs b/src/modules/annotate/dim_continue.rs index 22c9a25c6..02be66423 100644 --- a/src/modules/annotate/dim_continue.rs +++ b/src/modules/annotate/dim_continue.rs @@ -13,7 +13,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_continue.svg")); diff --git a/src/modules/annotate/dimjogline.rs b/src/modules/annotate/dimjogline.rs index 5f9cce128..243f3e949 100644 --- a/src/modules/annotate/dimjogline.rs +++ b/src/modules/annotate/dimjogline.rs @@ -9,7 +9,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_jog.svg")); diff --git a/src/modules/annotate/dimtedit.rs b/src/modules/annotate/dimtedit.rs index 029d86712..85b708757 100644 --- a/src/modules/annotate/dimtedit.rs +++ b/src/modules/annotate/dimtedit.rs @@ -9,7 +9,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_tedit.svg")); diff --git a/src/modules/annotate/leader_cmd.rs b/src/modules/annotate/leader_cmd.rs index d3be97fbe..1f5338f99 100644 --- a/src/modules/annotate/leader_cmd.rs +++ b/src/modules/annotate/leader_cmd.rs @@ -17,7 +17,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/leader.svg")); diff --git a/src/modules/annotate/linear_dim.rs b/src/modules/annotate/linear_dim.rs index 18735a2cc..2c47b0ed3 100644 --- a/src/modules/annotate/linear_dim.rs +++ b/src/modules/annotate/linear_dim.rs @@ -4,7 +4,7 @@ use acadrust::EntityType; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; use glam::Vec3; pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_linear.svg")); diff --git a/src/modules/annotate/mleader_cmd.rs b/src/modules/annotate/mleader_cmd.rs index 6b7706b83..f7fad9985 100644 --- a/src/modules/annotate/mleader_cmd.rs +++ b/src/modules/annotate/mleader_cmd.rs @@ -12,7 +12,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/mleader.svg")); diff --git a/src/modules/annotate/mleader_edit.rs b/src/modules/annotate/mleader_edit.rs index b6d70a707..eec4568b0 100644 --- a/src/modules/annotate/mleader_edit.rs +++ b/src/modules/annotate/mleader_edit.rs @@ -12,7 +12,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; // ── MLEADERADD ──────────────────────────────────────────────────────────────── diff --git a/src/modules/annotate/mtext.rs b/src/modules/annotate/mtext.rs index bbcd936db..90ef2a8fc 100644 --- a/src/modules/annotate/mtext.rs +++ b/src/modules/annotate/mtext.rs @@ -1,6 +1,6 @@ use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; use glam::Vec3; pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/mtext.svg")); diff --git a/src/modules/annotate/ordinate_dim.rs b/src/modules/annotate/ordinate_dim.rs index 5b03da5bc..c799a666b 100644 --- a/src/modules/annotate/ordinate_dim.rs +++ b/src/modules/annotate/ordinate_dim.rs @@ -15,7 +15,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub fn tool() -> ToolDef { ToolDef { diff --git a/src/modules/annotate/qdim.rs b/src/modules/annotate/qdim.rs index 88586c026..7e7e3803c 100644 --- a/src/modules/annotate/qdim.rs +++ b/src/modules/annotate/qdim.rs @@ -13,7 +13,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/qdim.svg")); diff --git a/src/modules/annotate/radius_dim.rs b/src/modules/annotate/radius_dim.rs index 8a0a270af..d81dfef7c 100644 --- a/src/modules/annotate/radius_dim.rs +++ b/src/modules/annotate/radius_dim.rs @@ -4,7 +4,7 @@ use acadrust::EntityType; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; use glam::Vec3; pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/dim_radius.svg")); diff --git a/src/modules/annotate/table_cmd.rs b/src/modules/annotate/table_cmd.rs index e9ad1fe5c..0b44731f9 100644 --- a/src/modules/annotate/table_cmd.rs +++ b/src/modules/annotate/table_cmd.rs @@ -14,7 +14,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/table.svg")); diff --git a/src/modules/annotate/text.rs b/src/modules/annotate/text.rs index cecbb3991..9b5e68197 100644 --- a/src/modules/annotate/text.rs +++ b/src/modules/annotate/text.rs @@ -1,6 +1,6 @@ use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; use glam::Vec3; pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/text.svg")); diff --git a/src/modules/annotate/tolerance_cmd.rs b/src/modules/annotate/tolerance_cmd.rs index 87aae917d..346f9d062 100644 --- a/src/modules/annotate/tolerance_cmd.rs +++ b/src/modules/annotate/tolerance_cmd.rs @@ -11,7 +11,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/tolerance.svg")); diff --git a/src/modules/home/clipboard/paste.rs b/src/modules/home/clipboard/paste.rs index 04a297c45..25e1b612a 100644 --- a/src/modules/home/clipboard/paste.rs +++ b/src/modules/home/clipboard/paste.rs @@ -17,7 +17,7 @@ use acadrust::Handle; use glam::Vec3; use crate::command::{CadCommand, CmdResult}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub struct PasteCommand { /// Wire models of the clipboard entities (used for preview). diff --git a/src/modules/home/draw/arc.rs b/src/modules/home/draw/arc.rs index b7a1ff466..79b1b4ba2 100644 --- a/src/modules/home/draw/arc.rs +++ b/src/modules/home/draw/arc.rs @@ -17,7 +17,7 @@ use acadrust::{Arc as CadArc, EntityType}; use crate::command::{CadCommand, CmdResult}; use crate::modules::IconKind; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; use glam::Vec3; const TAU: f32 = std::f32::consts::TAU; diff --git a/src/modules/home/draw/attdef.rs b/src/modules/home/draw/attdef.rs index 499b814a2..24f1014c4 100644 --- a/src/modules/home/draw/attdef.rs +++ b/src/modules/home/draw/attdef.rs @@ -12,7 +12,7 @@ use acadrust::EntityType; use glam::Vec3; use crate::command::{CadCommand, CmdResult}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; enum Step { Tag, diff --git a/src/modules/home/draw/circle.rs b/src/modules/home/draw/circle.rs index 91d44684e..1b0730ff1 100644 --- a/src/modules/home/draw/circle.rs +++ b/src/modules/home/draw/circle.rs @@ -14,7 +14,7 @@ use acadrust::{Circle, EntityType}; use crate::command::{CadCommand, CmdResult, DynField, TangentObject}; use crate::modules::home::defaults; use crate::modules::IconKind; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; use glam::Vec3; const TAU: f32 = std::f32::consts::TAU; diff --git a/src/modules/home/draw/ellipse.rs b/src/modules/home/draw/ellipse.rs index 8350e1b24..01fdb67c6 100644 --- a/src/modules/home/draw/ellipse.rs +++ b/src/modules/home/draw/ellipse.rs @@ -10,7 +10,7 @@ use acadrust::{Ellipse, EntityType}; use crate::command::{CadCommand, CmdResult}; use crate::modules::IconKind; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; use glam::Vec3; fn parse_f32(text: &str) -> Option { diff --git a/src/modules/home/draw/hatch.rs b/src/modules/home/draw/hatch.rs index 3e74dec6b..c2d9dc905 100644 --- a/src/modules/home/draw/hatch.rs +++ b/src/modules/home/draw/hatch.rs @@ -11,8 +11,8 @@ use crate::command::{CadCommand, CmdResult}; use crate::modules::IconKind; -use crate::scene::hatch_model::{HatchModel, HatchPattern, PatFamily}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::hatch_model::{HatchModel, HatchPattern, PatFamily}; +use crate::scene::model::wire_model::WireModel; use glam::Vec3; // ── Icons ────────────────────────────────────────────────────────────────── @@ -92,7 +92,7 @@ impl HatchCommand { fn make_hatch(&self, boundary: Vec<[f32; 2]>) -> HatchModel { // Default: ANSI31 from catalog; fallback to a single 45° family. let pat_name = "ANSI31"; - let families = crate::scene::hatch_patterns::find(pat_name) + let families = crate::scene::model::hatch_patterns::find(pat_name) .and_then(|e| { if let HatchPattern::Pattern(f) = &e.gpu { Some(f.clone()) diff --git a/src/modules/home/draw/line.rs b/src/modules/home/draw/line.rs index 27391b48e..8617b90a8 100644 --- a/src/modules/home/draw/line.rs +++ b/src/modules/home/draw/line.rs @@ -11,7 +11,7 @@ use acadrust::{EntityType, Line}; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; use glam::Vec3; // ── Ribbon definition ───────────────────────────────────────────────────── diff --git a/src/modules/home/draw/mline.rs b/src/modules/home/draw/mline.rs index e9a31b705..7539aee09 100644 --- a/src/modules/home/draw/mline.rs +++ b/src/modules/home/draw/mline.rs @@ -11,7 +11,7 @@ use acadrust::EntityType; use glam::Vec3; use crate::command::{CadCommand, CmdResult}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub struct MlineCommand { points: Vec, diff --git a/src/modules/home/draw/point.rs b/src/modules/home/draw/point.rs index 6ff164e95..14fad795e 100644 --- a/src/modules/home/draw/point.rs +++ b/src/modules/home/draw/point.rs @@ -8,7 +8,7 @@ use acadrust::{EntityType, Point as CadPoint}; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; use glam::Vec3; #[allow(dead_code)] diff --git a/src/modules/home/draw/polyline.rs b/src/modules/home/draw/polyline.rs index 2b3d9d1bc..df3ffb4dc 100644 --- a/src/modules/home/draw/polyline.rs +++ b/src/modules/home/draw/polyline.rs @@ -16,7 +16,7 @@ use glam::{Vec2, Vec3}; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; // ── Ribbon definition ────────────────────────────────────────────────────── diff --git a/src/modules/home/draw/raster_image.rs b/src/modules/home/draw/raster_image.rs index 5b93e9cd5..c5e210a0d 100644 --- a/src/modules/home/draw/raster_image.rs +++ b/src/modules/home/draw/raster_image.rs @@ -12,7 +12,7 @@ use acadrust::EntityType; use glam::Vec3; use crate::command::{CadCommand, CmdResult}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub struct ImageCommand { file_path: String, diff --git a/src/modules/home/draw/ray.rs b/src/modules/home/draw/ray.rs index 46330762a..39d733aed 100644 --- a/src/modules/home/draw/ray.rs +++ b/src/modules/home/draw/ray.rs @@ -9,7 +9,7 @@ use acadrust::types::Vector3; use acadrust::EntityType; use crate::command::{CadCommand, CmdResult}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; use glam::Vec3; const DISPLAY_EXTENT: f32 = 1_000_000.0; diff --git a/src/modules/home/draw/revcloud.rs b/src/modules/home/draw/revcloud.rs index aa77be11a..f1ab91613 100644 --- a/src/modules/home/draw/revcloud.rs +++ b/src/modules/home/draw/revcloud.rs @@ -11,7 +11,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../../assets/icons/revcloud.svg")); diff --git a/src/modules/home/draw/shapes.rs b/src/modules/home/draw/shapes.rs index 4b8b71948..c20eed469 100644 --- a/src/modules/home/draw/shapes.rs +++ b/src/modules/home/draw/shapes.rs @@ -16,7 +16,7 @@ use acadrust::{EntityType, LwPolyline}; use crate::command::{CadCommand, CmdResult}; use crate::modules::IconKind; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; use glam::Vec3; const TAU: f32 = std::f32::consts::TAU; diff --git a/src/modules/home/draw/spline.rs b/src/modules/home/draw/spline.rs index 35e1d8459..3b1f64440 100644 --- a/src/modules/home/draw/spline.rs +++ b/src/modules/home/draw/spline.rs @@ -8,7 +8,7 @@ use acadrust::{EntityType, Spline}; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; use glam::Vec3; #[allow(dead_code)] diff --git a/src/modules/home/draw/wipeout.rs b/src/modules/home/draw/wipeout.rs index c10e6ef46..77a8429c6 100644 --- a/src/modules/home/draw/wipeout.rs +++ b/src/modules/home/draw/wipeout.rs @@ -11,7 +11,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../../assets/icons/wipeout.svg")); diff --git a/src/modules/home/groups/group.rs b/src/modules/home/groups/group.rs index 99b3c8e22..572a07bb9 100644 --- a/src/modules/home/groups/group.rs +++ b/src/modules/home/groups/group.rs @@ -17,7 +17,7 @@ use acadrust::Handle; use glam::Vec3; use crate::command::{CadCommand, CmdResult}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub struct GroupCommand { handles: Vec, diff --git a/src/modules/home/groups/ungroup.rs b/src/modules/home/groups/ungroup.rs index d38d9666e..aea77e3b4 100644 --- a/src/modules/home/groups/ungroup.rs +++ b/src/modules/home/groups/ungroup.rs @@ -17,7 +17,7 @@ use acadrust::Handle; use glam::Vec3; use crate::command::{CadCommand, CmdResult}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub struct UngroupCommand; diff --git a/src/modules/home/inquiry/area.rs b/src/modules/home/inquiry/area.rs index 060a10579..5d61b153a 100644 --- a/src/modules/home/inquiry/area.rs +++ b/src/modules/home/inquiry/area.rs @@ -4,7 +4,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub struct AreaCommand { points: Vec, diff --git a/src/modules/home/inquiry/dist.rs b/src/modules/home/inquiry/dist.rs index 7290c5917..96523b6e9 100644 --- a/src/modules/home/inquiry/dist.rs +++ b/src/modules/home/inquiry/dist.rs @@ -3,7 +3,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub struct DistCommand { first: Option, diff --git a/src/modules/home/layers/match_layer.rs b/src/modules/home/layers/match_layer.rs index f60dd2768..1b9aaa89a 100644 --- a/src/modules/home/layers/match_layer.rs +++ b/src/modules/home/layers/match_layer.rs @@ -19,7 +19,7 @@ use acadrust::Handle; use glam::Vec3; use crate::command::{CadCommand, CmdResult}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub struct LayMatchCommand { dest_handles: Vec, diff --git a/src/modules/home/modify/array.rs b/src/modules/home/modify/array.rs index 023ea6197..52e8a9059 100644 --- a/src/modules/home/modify/array.rs +++ b/src/modules/home/modify/array.rs @@ -19,7 +19,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult, EntityTransform}; use crate::modules::home::defaults; use crate::modules::IconKind; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; // ── Dropdown constants ───────────────────────────────────────────────────── @@ -395,7 +395,7 @@ use std::f32::consts::TAU as FTAU; /// chord and ignored the extrusion, so arc-segment paths came out mirrored. fn lw_dense_pts(p: &acadrust::entities::LwPolyline) -> Vec { use crate::entities::common::BulgeArc; - use crate::scene::transform::ocs_point_to_wcs; + use crate::scene::view::transform::ocs_point_to_wcs; let verts = &p.vertices; if verts.is_empty() { @@ -547,7 +547,7 @@ impl ArrayPathCommand { // (normal = -Z) are traced on the same side the renderer draws, // matching `entities::arc::to_truck`. Sampling the raw centre + // angle ignores the extrusion and lands on the mirrored arc. - use crate::scene::transform::{ocs_axes, ocs_point_to_wcs}; + use crate::scene::view::transform::{ocs_axes, ocs_point_to_wcs}; let normal = (a.normal.x, a.normal.y, a.normal.z); let (ax, ay) = ocs_axes(normal); let (cx, cy, cz) = @@ -570,7 +570,7 @@ impl ArrayPathCommand { .collect() } EntityType::Circle(c) => { - use crate::scene::transform::{ocs_axes, ocs_point_to_wcs}; + use crate::scene::view::transform::{ocs_axes, ocs_point_to_wcs}; let normal = (c.normal.x, c.normal.y, c.normal.z); let (ax, ay) = ocs_axes(normal); let (cx, cy, cz) = diff --git a/src/modules/home/modify/attedit.rs b/src/modules/home/modify/attedit.rs index f609d0d27..a4be89ce5 100644 --- a/src/modules/home/modify/attedit.rs +++ b/src/modules/home/modify/attedit.rs @@ -10,7 +10,7 @@ use acadrust::EntityType; use glam::Vec3; use crate::command::{CadCommand, CmdResult}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub struct AtteditCommand { step: Step, diff --git a/src/modules/home/modify/break_cmd.rs b/src/modules/home/modify/break_cmd.rs index 4df6948a6..56775cea9 100644 --- a/src/modules/home/modify/break_cmd.rs +++ b/src/modules/home/modify/break_cmd.rs @@ -20,7 +20,7 @@ use truck_modeling::base::{BoundedCurve, Cut}; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; // ── Ribbon definition ────────────────────────────────────────────────────── diff --git a/src/modules/home/modify/copy.rs b/src/modules/home/modify/copy.rs index c23a5958a..f35a4b3af 100644 --- a/src/modules/home/modify/copy.rs +++ b/src/modules/home/modify/copy.rs @@ -10,7 +10,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult, EntityTransform}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; // ── Ribbon definition ────────────────────────────────────────────────────── diff --git a/src/modules/home/modify/fillet.rs b/src/modules/home/modify/fillet.rs index ccdd771ff..6c8fc6b03 100644 --- a/src/modules/home/modify/fillet.rs +++ b/src/modules/home/modify/fillet.rs @@ -19,7 +19,7 @@ const TAU: f64 = std::f64::consts::TAU; use crate::command::{CadCommand, CmdResult}; use crate::modules::home::defaults; use crate::modules::IconKind; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; // ── Dropdown constants ───────────────────────────────────────────────────── diff --git a/src/modules/home/modify/mirror.rs b/src/modules/home/modify/mirror.rs index cb0c65c81..023df3f23 100644 --- a/src/modules/home/modify/mirror.rs +++ b/src/modules/home/modify/mirror.rs @@ -13,7 +13,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult, EntityTransform}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub fn tool() -> ToolDef { ToolDef { diff --git a/src/modules/home/modify/offset.rs b/src/modules/home/modify/offset.rs index d4e2cbc06..d9e837271 100644 --- a/src/modules/home/modify/offset.rs +++ b/src/modules/home/modify/offset.rs @@ -23,7 +23,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult}; use crate::modules::home::defaults; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; // ── Ribbon definition ────────────────────────────────────────────────────── diff --git a/src/modules/home/modify/refedit.rs b/src/modules/home/modify/refedit.rs index a77ddbbd4..3b3ec6dad 100644 --- a/src/modules/home/modify/refedit.rs +++ b/src/modules/home/modify/refedit.rs @@ -128,7 +128,7 @@ impl CadCommand for RefCloseCommand { /// Order: scale → rotate (around origin) → translate. pub fn apply_insert_transform(entity: &mut EntityType, session: &RefEditSession) { use crate::command::EntityTransform; - use crate::scene::dispatch; + use crate::scene::view::dispatch; let origin = Vec3::ZERO; @@ -170,7 +170,7 @@ pub fn apply_insert_transform(entity: &mut EntityType, session: &RefEditSession) /// Order: un-translate → un-rotate → un-scale. pub fn apply_insert_inverse_transform(entity: &mut EntityType, session: &RefEditSession) { use crate::command::EntityTransform; - use crate::scene::dispatch; + use crate::scene::view::dispatch; let origin = Vec3::ZERO; diff --git a/src/modules/home/modify/rotate.rs b/src/modules/home/modify/rotate.rs index 2aad02b16..02f4077af 100644 --- a/src/modules/home/modify/rotate.rs +++ b/src/modules/home/modify/rotate.rs @@ -12,7 +12,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult, DynField, EntityTransform}; use crate::modules::home::defaults; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; // ── Ribbon definition ────────────────────────────────────────────────────── diff --git a/src/modules/home/modify/scale.rs b/src/modules/home/modify/scale.rs index 3e5bfc5ac..a052da8ea 100644 --- a/src/modules/home/modify/scale.rs +++ b/src/modules/home/modify/scale.rs @@ -18,7 +18,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult, EntityTransform}; use crate::modules::home::defaults; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; #[allow(dead_code)] pub fn tool() -> ToolDef { diff --git a/src/modules/home/modify/splinedit.rs b/src/modules/home/modify/splinedit.rs index 4fa3fcd67..d9032a9a8 100644 --- a/src/modules/home/modify/splinedit.rs +++ b/src/modules/home/modify/splinedit.rs @@ -14,7 +14,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; #[allow(dead_code)] pub fn tool() -> ToolDef { diff --git a/src/modules/home/modify/stretch.rs b/src/modules/home/modify/stretch.rs index 32fb994d7..f1a048ccc 100644 --- a/src/modules/home/modify/stretch.rs +++ b/src/modules/home/modify/stretch.rs @@ -20,7 +20,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; // ── Ribbon definition ────────────────────────────────────────────────────── diff --git a/src/modules/home/modify/translate.rs b/src/modules/home/modify/translate.rs index c4a8893a3..a4ac31727 100644 --- a/src/modules/home/modify/translate.rs +++ b/src/modules/home/modify/translate.rs @@ -10,7 +10,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult, EntityTransform}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; // ── Ribbon definition ────────────────────────────────────────────────────── diff --git a/src/modules/home/modify/trim.rs b/src/modules/home/modify/trim.rs index 505951a91..21c741365 100644 --- a/src/modules/home/modify/trim.rs +++ b/src/modules/home/modify/trim.rs @@ -25,7 +25,7 @@ use crate::modules::home::modify::spline_ops::{ t_to_rel, }; use crate::modules::IconKind; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; // ── Dropdown constants ───────────────────────────────────────────────────── diff --git a/src/modules/home/properties/match_prop.rs b/src/modules/home/properties/match_prop.rs index 2f92c1bb1..fb4ad1042 100644 --- a/src/modules/home/properties/match_prop.rs +++ b/src/modules/home/properties/match_prop.rs @@ -17,7 +17,7 @@ use acadrust::Handle; use glam::Vec3; use crate::command::{CadCommand, CmdResult}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub struct MatchPropCommand { /// Source handle; NULL until phase 1 is complete. diff --git a/src/modules/home/select.rs b/src/modules/home/select.rs index e1cbe7a49..9be87092d 100644 --- a/src/modules/home/select.rs +++ b/src/modules/home/select.rs @@ -9,7 +9,7 @@ use acadrust::Handle; use glam::Vec3; use crate::command::{CadCommand, CmdResult}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub struct SelectObjectsCommand { pending_cmd: String, diff --git a/src/modules/insert/create_block.rs b/src/modules/insert/create_block.rs index 346664c6c..18f1f84d6 100644 --- a/src/modules/insert/create_block.rs +++ b/src/modules/insert/create_block.rs @@ -3,7 +3,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub fn tool() -> ToolDef { ToolDef { diff --git a/src/modules/insert/insert_block.rs b/src/modules/insert/insert_block.rs index 655e10f51..4ed006500 100644 --- a/src/modules/insert/insert_block.rs +++ b/src/modules/insert/insert_block.rs @@ -5,7 +5,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub fn tool() -> ToolDef { ToolDef { diff --git a/src/modules/insert/xattach.rs b/src/modules/insert/xattach.rs index 36e555a08..f6c79a880 100644 --- a/src/modules/insert/xattach.rs +++ b/src/modules/insert/xattach.rs @@ -16,7 +16,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; use crate::scene::Scene; pub fn tool() -> ToolDef { diff --git a/src/modules/layout/mview.rs b/src/modules/layout/mview.rs index 5fcd8edde..399218a62 100644 --- a/src/modules/layout/mview.rs +++ b/src/modules/layout/mview.rs @@ -10,7 +10,7 @@ use acadrust::EntityType; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; use glam::Vec3; // ── Ribbon definition ───────────────────────────────────────────────────── diff --git a/src/modules/layout/vplayer.rs b/src/modules/layout/vplayer.rs index 45e87ef51..787934587 100644 --- a/src/modules/layout/vplayer.rs +++ b/src/modules/layout/vplayer.rs @@ -14,7 +14,7 @@ use acadrust::Handle; use glam::Vec3; use crate::command::{CadCommand, CmdResult}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub struct VplayerCommand { vp_handle: Handle, diff --git a/src/modules/manage/mview.rs b/src/modules/manage/mview.rs index c4f2ee410..559136e91 100644 --- a/src/modules/manage/mview.rs +++ b/src/modules/manage/mview.rs @@ -10,7 +10,7 @@ use acadrust::EntityType; use crate::command::{CadCommand, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; use glam::Vec3; // ── Ribbon definition ───────────────────────────────────────────────────── diff --git a/src/modules/model/primitive_cmd.rs b/src/modules/model/primitive_cmd.rs index 874f28217..bfb0ea036 100644 --- a/src/modules/model/primitive_cmd.rs +++ b/src/modules/model/primitive_cmd.rs @@ -13,8 +13,8 @@ use glam::Vec3; use truck_modeling::Solid; use crate::command::{CadCommand, CmdResult}; -use crate::scene::model_solid; -use crate::scene::wire_model::WireModel; +use crate::scene::model::model_solid; +use crate::scene::model::wire_model::WireModel; /// Which primitive a `PrimitiveCommand` builds. #[derive(Clone, Copy, PartialEq, Eq)] diff --git a/src/modules/view/plot_window.rs b/src/modules/view/plot_window.rs index dd9f4959e..2af83afa1 100644 --- a/src/modules/view/plot_window.rs +++ b/src/modules/view/plot_window.rs @@ -4,7 +4,7 @@ // window to the layout's PlotSettings (PlotType::Window). use crate::command::{CadCommand, CmdResult}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; use glam::Vec3; pub struct PlotWindowCommand { diff --git a/src/modules/view/zoom_window.rs b/src/modules/view/zoom_window.rs index 0cb2d510b..12c40a7a4 100644 --- a/src/modules/view/zoom_window.rs +++ b/src/modules/view/zoom_window.rs @@ -3,7 +3,7 @@ use glam::Vec3; use crate::command::{CadCommand, CmdResult}; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; pub struct ZoomWindowCommand { first: Option, diff --git a/src/scene/block_cache.rs b/src/scene/cache/block_cache.rs similarity index 99% rename from src/scene/block_cache.rs rename to src/scene/cache/block_cache.rs index 0393b7e94..faf766d8b 100644 --- a/src/scene/block_cache.rs +++ b/src/scene/cache/block_cache.rs @@ -21,8 +21,8 @@ use std::sync::Arc; use acadrust::types::{Color as AcadColor, LineWeight, Transform, Vector3}; use acadrust::{CadDocument, EntityType, Handle}; -use crate::scene::tessellate; -use crate::scene::wire_model::{SnapHint, TangentGeom, WireModel}; +use crate::scene::convert::tessellate; +use crate::scene::model::wire_model::{SnapHint, TangentGeom, WireModel}; const MAX_NESTING_DEPTH: usize = 32; /// Skip wires whose world-AABB projects to fewer than this many pixels in @@ -392,7 +392,7 @@ fn build_nested_ref( // (`Batches::finalize`) so the same cached defn can serve renders // against different backgrounds without rebuilding. let (ins_color, ins_pat_len, ins_pat, ins_lw_px, _) = - crate::scene::render::render_style_for(doc, &EntityType::Insert(nested_ins.clone())); + crate::scene::view::render::render_style_for(doc, &EntityType::Insert(nested_ins.clone())); let _ = bg_color; NestedRef { @@ -430,7 +430,7 @@ fn tessellate_sub_local( // with the per-render bg, so the cache no longer has to rebuild on // BACKGROUND / layout-switch — the dynamic adaptation tracks the // live bg at render time. - let (sub_color, pat_len, pat, lw_px, aci) = crate::scene::render::render_style_for(doc, sub); + let (sub_color, pat_len, pat, lw_px, aci) = crate::scene::view::render::render_style_for(doc, sub); let _ = bg_color; let color_is_byblock = sub.common().color == AcadColor::ByBlock; @@ -1087,7 +1087,7 @@ impl Batches { // now so each render against a different bg gets the // right pure-black ↔ pure-white flip without rebuilding // the cached defn. - let color = crate::scene::render::adapt_to_bg(b.color, bg_color); + let color = crate::scene::view::render::adapt_to_bg(b.color, bg_color); WireModel { name: name.to_string(), points: b.points, diff --git a/src/scene/cache/mod.rs b/src/scene/cache/mod.rs new file mode 100644 index 000000000..b32ee0b29 --- /dev/null +++ b/src/scene/cache/mod.rs @@ -0,0 +1,2 @@ +pub mod block_cache; +pub mod properties; diff --git a/src/scene/properties.rs b/src/scene/cache/properties.rs similarity index 96% rename from src/scene/properties.rs rename to src/scene/cache/properties.rs index 0f431d9b9..135f254e9 100644 --- a/src/scene/properties.rs +++ b/src/scene/cache/properties.rs @@ -1,6 +1,6 @@ use acadrust::{EntityType, Handle}; -use crate::scene::object::{PropSection, PropValue, Property}; +use crate::scene::model::object::{PropSection, PropValue, Property}; pub fn general_section(entity: &EntityType) -> PropSection { let common = entity.common(); diff --git a/src/scene/acad_to_truck.rs b/src/scene/convert/acad_to_truck.rs similarity index 97% rename from src/scene/acad_to_truck.rs rename to src/scene/convert/acad_to_truck.rs index 9c03ff510..4298f019a 100644 --- a/src/scene/acad_to_truck.rs +++ b/src/scene/convert/acad_to_truck.rs @@ -5,7 +5,7 @@ use glam::Vec3; use truck_modeling::{Edge, Solid, Vertex, Wire}; use crate::entities::traits::EntityTypeOps; -use crate::scene::wire_model::{SnapHint, TangentGeom}; +use crate::scene::model::wire_model::{SnapHint, TangentGeom}; /// One group of glyph strokes with its world-space origin stored in f64. /// Strokes are in glyph-local space (origin = [0,0]) so that the large diff --git a/src/scene/acis_to_truck.rs b/src/scene/convert/acis_to_truck.rs similarity index 98% rename from src/scene/acis_to_truck.rs rename to src/scene/convert/acis_to_truck.rs index 77ea20796..4c079f4df 100644 --- a/src/scene/acis_to_truck.rs +++ b/src/scene/convert/acis_to_truck.rs @@ -26,8 +26,8 @@ use acadrust::entities::acis::{ SatConeSurface, SatDocument, SatFace, SatPlaneSurface, SatSphereSurface, SatTorusSurface, }; -use crate::scene::mesh_model::{MeshLodSet, MeshModel}; -use crate::scene::solid3d_tess::{ +use crate::scene::model::mesh_model::{MeshLodSet, MeshModel}; +use crate::scene::convert::solid3d_tess::{ apply_body_transform, body_transform, collect_face_polygon, cone_axis_span, mesh_aabb, }; @@ -302,7 +302,7 @@ fn torus_faces(torus: &SatTorusSurface) -> Vec { /// Append meshes for every `spline-surface` face, reusing the truck /// BSplineSurface grid sampler in `spline_tess`. fn append_spline_faces(sat: &SatDocument, mesh: &mut MeshModel) { - use crate::scene::solid3d_tess::LodConfig; + use crate::scene::convert::solid3d_tess::LodConfig; for face in sat.faces() { let Some(surf_rec) = sat.resolve(face.surface()) else { continue; @@ -313,7 +313,7 @@ fn append_spline_faces(sat: &SatDocument, mesh: &mut MeshModel) { let mut verts: Vec<[f32; 3]> = Vec::new(); let mut normals: Vec<[f32; 3]> = Vec::new(); let mut indices: Vec = Vec::new(); - crate::scene::spline_tess::tess_spline_face( + crate::scene::convert::spline_tess::tess_spline_face( sat, &face, LodConfig::HIGH, diff --git a/src/scene/convert/mod.rs b/src/scene/convert/mod.rs new file mode 100644 index 000000000..306bb3b6f --- /dev/null +++ b/src/scene/convert/mod.rs @@ -0,0 +1,7 @@ +pub mod acad_to_truck; +pub mod acis_to_truck; +pub mod truck_tess; +pub mod tessellate; +pub mod tess_util; +pub mod solid3d_tess; +pub mod spline_tess; diff --git a/src/scene/solid3d_tess.rs b/src/scene/convert/solid3d_tess.rs similarity index 99% rename from src/scene/solid3d_tess.rs rename to src/scene/convert/solid3d_tess.rs index 2acac3742..42ad27195 100644 --- a/src/scene/solid3d_tess.rs +++ b/src/scene/convert/solid3d_tess.rs @@ -20,7 +20,7 @@ use acadrust::entities::acis::{ }; use acadrust::entities::{Body, Region, Solid3D}; -use crate::scene::mesh_model::{MeshLodSet, MeshModel}; +use crate::scene::model::mesh_model::{MeshLodSet, MeshModel}; /// Per-LOD sampling density. Higher values = finer mesh = more triangles. #[derive(Copy, Clone, Debug)] @@ -107,7 +107,7 @@ fn tessellate_sat( } } "spline-surface" => { - crate::scene::spline_tess::tess_spline_face( + crate::scene::convert::spline_tess::tess_spline_face( sat, &face, lod, @@ -141,7 +141,7 @@ fn tessellate_acis( color: [f32; 4], facet_res: f64, ) -> Option { - if let Some(set) = crate::scene::acis_to_truck::tessellate_sat_truck(sat, name.clone(), color, facet_res) { + if let Some(set) = crate::scene::convert::acis_to_truck::tessellate_sat_truck(sat, name.clone(), color, facet_res) { if std::env::var_os("OCS_TESS_DEBUG").is_some() { let tris = set.lods.first().map(|m| m.indices.len() / 3).unwrap_or(0); eprintln!("acis_tess[{name}]: truck ({tris} tris)"); diff --git a/src/scene/spline_tess.rs b/src/scene/convert/spline_tess.rs similarity index 99% rename from src/scene/spline_tess.rs rename to src/scene/convert/spline_tess.rs index 02681e954..ba2850432 100644 --- a/src/scene/spline_tess.rs +++ b/src/scene/convert/spline_tess.rs @@ -10,7 +10,7 @@ use acadrust::entities::acis::{SatDocument, SatFace, SatRecord, SatToken}; use truck_modeling::{BSplineSurface, KnotVec, ParametricSurface, ParametricSurface3D, Point3}; -use crate::scene::solid3d_tess::LodConfig; +use crate::scene::convert::solid3d_tess::LodConfig; /// Tessellate one `spline-surface` face by sampling its B-spline surface. /// Appends triangles to the shared mesh buffers; a no-op when the surface diff --git a/src/scene/tess_util.rs b/src/scene/convert/tess_util.rs similarity index 95% rename from src/scene/tess_util.rs rename to src/scene/convert/tess_util.rs index b2a2154f5..d4ae0b8d5 100644 --- a/src/scene/tess_util.rs +++ b/src/scene/convert/tess_util.rs @@ -1,5 +1,5 @@ // Shared helpers used by per-entity tessellation impls in `crate::entities` -// and the dispatcher in `crate::scene::tessellate`. +// and the dispatcher in `crate::scene::convert::tessellate`. // // Anything cross-entity (colour resolution, arc sampling, chord tolerance) // lives here. Entity-specific helpers (dim format strings, mleader path @@ -8,7 +8,7 @@ use acadrust::types::Color as AcadColor; use glam::Vec3; -use crate::scene::wire_model::{SnapHint, TangentGeom, WireModel}; +use crate::scene::model::wire_model::{SnapHint, TangentGeom, WireModel}; /// Output of the fallback per-entity geometry path used by entities not /// covered by the truck topology pipeline (Viewport, Insert, Hatch @@ -80,7 +80,7 @@ pub fn fill_chord_tol(radius: f64) -> f64 { /// passes, load-time builds), falls back to [`fill_chord_tol`] so we /// never under-sample. pub fn wire_chord_tol(radius: f64) -> f64 { - match crate::scene::truck_tess::active_curve_tol() { + match crate::scene::convert::truck_tess::active_curve_tol() { Some(t) => t.min(fill_chord_tol(radius)).max(1e-9), None => fill_chord_tol(radius), } diff --git a/src/scene/tessellate.rs b/src/scene/convert/tessellate.rs similarity index 99% rename from src/scene/tessellate.rs rename to src/scene/convert/tessellate.rs index 9163473c9..2005597b8 100644 --- a/src/scene/tessellate.rs +++ b/src/scene/convert/tessellate.rs @@ -18,11 +18,11 @@ use acadrust::types::Color as AcadColor; use acadrust::{CadDocument, EntityType, Handle}; use glam::Vec3; -use crate::scene::acad_to_truck::{convert, TruckObject}; -use crate::scene::truck_tess::{ +use crate::scene::convert::acad_to_truck::{convert, TruckObject}; +use crate::scene::convert::truck_tess::{ tessellate_edge, tessellate_vertex, tessellate_wire, TruckTessResult, }; -use crate::scene::wire_model::{SnapHint, WireModel}; +use crate::scene::model::wire_model::{SnapHint, WireModel}; // ── Public entry points ──────────────────────────────────────────────────── @@ -604,7 +604,7 @@ pub(crate) fn entity_z(entity: &EntityType) -> f32 { // function stays as the dispatcher used by the main `tessellate()` path. use crate::entities::traits::FallbackTess; -use crate::scene::tess_util::FallbackGeometry as Geometry; +use crate::scene::convert::tess_util::FallbackGeometry as Geometry; fn fallback_geometry(entity: &EntityType, world_offset: [f64; 3]) -> Geometry { match entity { diff --git a/src/scene/truck_tess.rs b/src/scene/convert/truck_tess.rs similarity index 100% rename from src/scene/truck_tess.rs rename to src/scene/convert/truck_tess.rs diff --git a/src/scene/mod.rs b/src/scene/mod.rs index 1d1fd8355..1d3587daa 100644 --- a/src/scene/mod.rs +++ b/src/scene/mod.rs @@ -1,56 +1,38 @@ -pub mod acad_to_truck; -pub mod block_cache; -mod camera; -pub mod complex_lt; -pub mod lff; -pub mod dispatch; -pub mod font_face; -pub mod grip; -pub mod hatch_model; -pub mod hatch_patterns; -pub mod hit_test; -pub mod image_model; -pub mod mesh_model; -pub mod model_solid; -pub mod object; +// Scene modules grouped by role: +// convert — DXF/ACIS entities → truck solids & tessellated geometry +// text — LFF stroke + TrueType font engines and shaping +// model — per-entity GPU render models (wire, hatch, mesh, image, object) +// pick — hit-testing, selection, grips, spatial index, xclip +// view — camera, transforms, viewport, render pipeline driver +// cache — block-definition and property caches +pub mod cache; +pub mod convert; +pub mod model; +pub mod pick; pub mod pipeline; -pub mod properties; -pub mod quadtree; +pub mod text; +pub mod view; /// Result of `Scene::entity_index()`. The wire path queries `tree` for /// view-rect candidates and also always emits `unbounded_handles` /// (entities with no usable bbox — legacy `UNBOUNDED_AABB` sentinel). pub(super) struct EntityIndex { - pub tree: quadtree::QuadTree, + pub tree: pick::quadtree::QuadTree, pub unbounded_handles: Vec, } -pub(crate) mod render; -mod selection; -pub mod acis_to_truck; -pub mod solid3d_tess; -pub mod spline_tess; -pub mod sysfont; -pub mod ttf_glyph; -pub mod tess_util; -pub mod tessellate; -pub mod transform; -pub mod truck_tess; -pub mod viewport_pane; -pub mod wire_model; -pub mod xclip; -use camera::Camera; -pub use camera::Projection; -pub use hatch_model::HatchModel; -pub use image_model::ImageModel; -pub use mesh_model::MeshLodSet; -pub use object::{GripApply, GripDef}; +use view::camera::Camera; +pub use view::camera::Projection; +pub use model::hatch_model::HatchModel; +pub use model::image_model::ImageModel; +pub use model::mesh_model::MeshLodSet; +pub use model::object::{GripApply, GripDef}; pub use pipeline::uniforms::Uniforms; pub use pipeline::viewcube::{ hit_test, hover_id, CubeRegion, VIEWCUBE_DRAW_PX, VIEWCUBE_PAD, VIEWCUBE_PX, }; -pub use selection::SelectionState; -pub use wire_model::WireModel; +pub use pick::selection::SelectionState; +pub use model::wire_model::WireModel; use crate::command::EntityTransform; use acadrust::entities::{Block, BlockEnd, Insert as DxfInsert}; @@ -170,7 +152,7 @@ pub fn build_derived_caches(doc: &CadDocument) -> DerivedCaches { // // Cross-check the header against a per-entity AABB scan of MSPACE // (same `bounding_box()` API and same SANE_EXTENT/zero-placeholder - // filters that `block_cache::build_defn` already uses for block defns) + // filters that `cache::block_cache::build_defn` already uses for block defns) // and prefer the entity-scan when the header center drifts more than // 10× its own half-span away from the entity centroid. use rayon::prelude::*; @@ -219,8 +201,8 @@ pub fn build_derived_caches(doc: &CadDocument) -> DerivedCaches { } else { [0.0; 3] }; - let (raw, ..) = render::render_style_for(doc, e); - let color = render::adapt_to_bg(raw, LOAD_BG); + let (raw, ..) = view::render::render_style_for(doc, e); + let color = view::render::adapt_to_bg(raw, LOAD_BG); let model = match e { EntityType::Hatch(dxf) => Scene::hatch_model_from_dxf(dxf, color, offset), EntityType::Solid(solid) => Some(Scene::solid_hatch_model(solid, color, offset)), @@ -250,8 +232,8 @@ pub fn build_derived_caches(doc: &CadDocument) -> DerivedCaches { .par_iter() .filter_map(|&handle| { let e = doc.get_entity(handle)?; - let (raw, ..) = render::render_style_for(doc, e); - let color = render::adapt_to_bg(raw, LOAD_BG); + let (raw, ..) = view::render::render_style_for(doc, e); + let color = view::render::adapt_to_bg(raw, LOAD_BG); crate::entities::solid3d::tessellate_volume(e, color, facet_res) .map(|m| (handle, offset_mesh_lod_set(m, world_offset))) }) @@ -268,7 +250,7 @@ pub fn build_derived_caches(doc: &CadDocument) -> DerivedCaches { } } -/// Mirrors `block_cache::SANE_EXTENT` — wire coords past this magnitude +/// Mirrors `cache::block_cache::SANE_EXTENT` — wire coords past this magnitude /// are treated as corruption rather than precision-relevant geometry. const WORLD_OFFSET_SANE_EXTENT: f64 = 1.0e8; @@ -342,7 +324,7 @@ fn offset_centroid( return None; } // Skip block-defn sentinels and AttributeDefinition — same as - // block_cache::build_defn. Their bboxes don't represent drawable + // cache::block_cache::build_defn. Their bboxes don't represent drawable // MSPACE geometry. if matches!( e, @@ -735,7 +717,7 @@ pub struct Scene { /// Tessellated block definitions in block-local coords, keyed by geometry_epoch. /// Lets Insert tessellation transform-copy cached wires instead of /// clone+explode+re-tessellate per reference. - block_defn_cache: RefCell)>>, + block_defn_cache: RefCell)>>, /// Spatial index + always-emit list for top-level entities /// (Phase 2.1). Lazily rebuilt by `entity_index()` on /// `geometry_epoch` change. See `EntityIndex` for what each side @@ -946,7 +928,7 @@ impl Scene { /// Get (or build on miss) the block-definition cache for the current epoch. /// Built single-threaded — recursive nested expansion makes parallelization /// fiddly and the cache only rebuilds when geometry actually changes. - pub(super) fn block_cache_arc(&self) -> Arc { + pub(super) fn block_cache_arc(&self) -> Arc { { let cache = self.block_defn_cache.borrow(); if let Some((epoch, ref arc)) = *cache { @@ -965,7 +947,7 @@ impl Scene { } else { 1.0 }; - let built = block_cache::BlockCache::build(&self.document, anno, bg); + let built = cache::block_cache::BlockCache::build(&self.document, anno, bg); let arc = Arc::new(built); *self.block_defn_cache.borrow_mut() = Some((self.block_epoch, Arc::clone(&arc))); arc @@ -1035,7 +1017,7 @@ impl Scene { .get_entity(handle) .map(|e| self.render_style(e).0) .unwrap_or([0.8, 0.8, 0.85, 1.0]); - if let Some(set) = crate::scene::model_solid::mesh_from_solid(&solid, color) { + if let Some(set) = crate::scene::model::model_solid::mesh_from_solid(&solid, color) { self.meshes.insert(handle, set); } self.model_solids.insert(handle, solid); @@ -1328,7 +1310,7 @@ impl Scene { Some(HatchModel { world_origin: [0.0, 0.0], boundary: Arc::new(vec![[x0, y0], [x1, y0], [x1, y1], [x0, y1], [x0, y0]]), - pattern: crate::scene::hatch_model::HatchPattern::Solid, + pattern: crate::scene::model::hatch_model::HatchPattern::Solid, name: "SOLID".to_string(), color: self.paper_bg_color, angle_offset: 0.0, @@ -2115,7 +2097,7 @@ impl Scene { .meshes .iter() .filter_map(|(h, set)| set.lods.first().map(|m| (*h, m))); - hit_test::mesh_click_hit(cursor, iter, view_proj, bounds) + pick::hit_test::mesh_click_hit(cursor, iter, view_proj, bounds) } /// Tessellate all non-invisible entities owned by `block_handle`. @@ -2297,7 +2279,7 @@ impl Scene { 1.0 }; let blk_cache = self.block_cache_arc(); - let blk_ref: &block_cache::BlockCache = &blk_cache; + let blk_ref: &cache::block_cache::BlockCache = &blk_cache; // Zoom-adaptive curve sampling for top-level Edge tessellation. Target // ~0.5 px chord height — far-out arcs that used to emit hundreds of // segments now collapse to a handful. The guard clears the override @@ -2306,11 +2288,11 @@ impl Scene { struct CurveTolGuard; impl Drop for CurveTolGuard { fn drop(&mut self) { - crate::scene::truck_tess::set_curve_tol_override(None); + crate::scene::convert::truck_tess::set_curve_tol_override(None); } } let _tol_guard = wpp.map(|w| { - crate::scene::truck_tess::set_curve_tol_override(Some((w * 0.5) as f64)); + crate::scene::convert::truck_tess::set_curve_tol_override(Some((w * 0.5) as f64)); CurveTolGuard }); // Per-entity tessellation memo (Phase 2.2) — only on the culled Model @@ -2550,7 +2532,7 @@ impl Scene { } None => [-1.0, -1.0, 1.0, 1.0], }; - let mut tree = quadtree::QuadTree::new(root); + let mut tree = pick::quadtree::QuadTree::new(root); for (h, ab) in items { tree.insert(h, ab); } @@ -3021,7 +3003,7 @@ impl Scene { continue; } - let adapted = render::adapt_to_bg(wire.color, self.paper_bg_color); + let adapted = view::render::adapt_to_bg(wire.color, self.paper_bg_color); let [r, g, b, a] = adapted; let mut out = wire.clone(); out.points = clipped; @@ -3521,7 +3503,7 @@ impl Scene { let color = layer_entry .map(|l| &l.color) .unwrap_or(&acadrust::types::Color::WHITE); - let [r, g, b, _] = crate::scene::tess_util::aci_to_rgba(color); + let [r, g, b, _] = crate::scene::convert::tess_util::aci_to_rgba(color); [r, g, b, 1.0] } @@ -3589,7 +3571,7 @@ impl Scene { let local = EntityTransform::Translate(-base); for (old_handle, mut entity) in source_entities { - dispatch::apply_transform(&mut entity, &local); + view::dispatch::apply_transform(&mut entity, &local); entity = crate::modules::home::modify::explode::normalize_entity_for_block(entity); entity.common_mut().handle = Handle::NULL; entity.common_mut().owner_handle = br_handle; @@ -3667,7 +3649,7 @@ impl Scene { m.color = self.render_style(e).0; if let EntityType::Hatch(dxf) = e { match &mut m.pattern { - hatch_model::HatchPattern::Pattern(_) => { + model::hatch_model::HatchPattern::Pattern(_) => { m.angle_offset = dxf.pattern_angle as f32; let anno = if self.current_layout == "Model" { self.annotation_scale @@ -3676,10 +3658,10 @@ impl Scene { }; m.scale = dxf.pattern_scale as f32 * anno; } - hatch_model::HatchPattern::Gradient { angle_deg, .. } => { + model::hatch_model::HatchPattern::Gradient { angle_deg, .. } => { *angle_deg = dxf.pattern_angle.to_degrees() as f32; } - hatch_model::HatchPattern::Solid => {} + model::hatch_model::HatchPattern::Solid => {} } } } @@ -3708,8 +3690,8 @@ impl Scene { let selected = self.selected.contains(&ins.common.handle); // XCLIP: clip this insert's exploded hatch fills to the boundary, // matching how the line geometry is clipped in expand_insert. - let clip_poly = xclip::insert_spatial_filter(&self.document, ins) - .map(|sf| xclip::world_clip_polygon(sf, ins, hatch_offset)); + let clip_poly = pick::xclip::insert_spatial_filter(&self.document, ins) + .map(|sf| pick::xclip::world_clip_polygon(sf, ins, hatch_offset)); // Walk the full block tree: `explode_from_document` only descends // one level, so nested INSERTs are re-exploded here. Each level // bakes its transform into the children it returns, so nested @@ -3740,7 +3722,7 @@ impl Scene { Self::hatch_model_from_dxf(&dxf, color, hatch_offset) { if let Some(poly) = &clip_poly { - let clipped = xclip::clip_hatch_boundary( + let clipped = pick::xclip::clip_hatch_boundary( &model.boundary, model.world_origin, poly, @@ -3797,7 +3779,7 @@ impl Scene { } models.push(HatchModel { boundary: Arc::new(boundary), - pattern: hatch_model::HatchPattern::Solid, + pattern: model::hatch_model::HatchPattern::Solid, name: "SOLID".into(), color, angle_offset: 0.0, @@ -3861,7 +3843,7 @@ impl Scene { } models.push(HatchModel { boundary: Arc::new(boundary), - pattern: hatch_model::HatchPattern::Solid, + pattern: model::hatch_model::HatchPattern::Solid, name: "WIPEOUT_FILL".into(), color: fill_color, angle_offset: 0.0, @@ -3957,7 +3939,7 @@ impl Scene { // even on large UTM-scale drawings. let to_xy = |x: f64, y: f64| -> [f64; 2] { let (wx, wy, _) = - crate::scene::transform::ocs_point_to_wcs((x, y, dxf.elevation), normal); + crate::scene::view::transform::ocs_point_to_wcs((x, y, dxf.elevation), normal); [wx - ox, wy - oy] }; if dxf.paths.is_empty() { @@ -4006,10 +3988,10 @@ impl Scene { boundary.push(to_xy(v0.x, v0.y)); continue; }; - let segs = tess_util::arc_segments( + let segs = convert::tess_util::arc_segments( arc.radius, arc.sweep.abs(), - tess_util::fill_chord_tol(arc.radius), + convert::tess_util::fill_chord_tol(arc.radius), ); for j in 0..segs { let s = arc.sample(j as f64 / segs as f64); @@ -4027,15 +4009,15 @@ impl Scene { boundary.push(to_xy(line.end.x, line.end.y)); } BoundaryEdge::CircularArc(arc) => { - let (sa, span) = tess_util::arc_signed_span( + let (sa, span) = convert::tess_util::arc_signed_span( arc.start_angle, arc.end_angle, arc.counter_clockwise, ); - let segs = tess_util::arc_segments( + let segs = convert::tess_util::arc_segments( arc.radius, span.abs(), - tess_util::fill_chord_tol(arc.radius), + convert::tess_util::fill_chord_tol(arc.radius), ); for i in 0..=segs { let t = sa + span * (i as f64 / segs as f64); @@ -4054,15 +4036,15 @@ impl Scene { .major_axis_endpoint .y .atan2(ell.major_axis_endpoint.x); - let (sa, span) = tess_util::arc_signed_span( + let (sa, span) = convert::tess_util::arc_signed_span( ell.start_angle, ell.end_angle, ell.counter_clockwise, ); - let segs = tess_util::arc_segments( + let segs = convert::tess_util::arc_segments( r_maj, span.abs(), - tess_util::fill_chord_tol(r_maj), + convert::tess_util::fill_chord_tol(r_maj), ); let (cr, sr) = (rot.cos(), rot.sin()); for i in 0..=segs { @@ -4116,7 +4098,7 @@ impl Scene { let diag = ((sp_max_x - sp_min_x).powi(2) + (sp_max_y - sp_min_y).powi(2)) .sqrt(); - let tol = tess_util::fill_chord_tol(diag.max(1.0)); + let tol = convert::tess_util::fill_chord_tol(diag.max(1.0)); let mut sampled = false; if knot_ok { @@ -4193,7 +4175,7 @@ impl Scene { if boundary.is_empty() { return None; } - boundary.truncate(hatch_model::MAX_HATCH_BOUNDARY_VERTS); + boundary.truncate(model::hatch_model::MAX_HATCH_BOUNDARY_VERTS); let pattern = if dxf.gradient_color.is_enabled() { let color2 = dxf @@ -4204,15 +4186,15 @@ impl Scene { .map(|(r, g, b)| [r as f32 / 255.0, g as f32 / 255.0, b as f32 / 255.0, 1.0]) .unwrap_or(color); let angle_deg = dxf.pattern_angle.to_degrees() as f32; - hatch_model::HatchPattern::Gradient { angle_deg, color2 } + model::hatch_model::HatchPattern::Gradient { angle_deg, color2 } } else if dxf.is_solid { - hatch_model::HatchPattern::Solid + model::hatch_model::HatchPattern::Solid } else { let pat_name = &dxf.pattern.name; - if let Some(entry) = crate::scene::hatch_patterns::find(pat_name) { + if let Some(entry) = crate::scene::model::hatch_patterns::find(pat_name) { entry.gpu.clone() } else { - hatch_model::HatchPattern::Pattern(vec![hatch_model::PatFamily { + model::hatch_model::HatchPattern::Pattern(vec![model::hatch_model::PatFamily { angle_deg: 0.0, x0: 0.0, y0: 0.0, @@ -4329,11 +4311,11 @@ impl Scene { }; let model = match &kind { EntityType::Hatch(dxf) => { - let color = tess_util::aci_to_rgba(&dxf.common.color); + let color = convert::tess_util::aci_to_rgba(&dxf.common.color); Self::hatch_model_from_dxf(dxf, color, offset) } EntityType::Solid(solid) => { - let color = tess_util::aci_to_rgba(&solid.common.color); + let color = convert::tess_util::aci_to_rgba(&solid.common.color); Some(Self::solid_hatch_model(solid, color, offset)) } _ => None, @@ -4415,7 +4397,7 @@ impl Scene { ]; HatchModel { boundary: std::sync::Arc::new(boundary), - pattern: hatch_model::HatchPattern::Solid, + pattern: model::hatch_model::HatchPattern::Solid, name: "SOLID".into(), color, angle_offset: 0.0, @@ -4430,7 +4412,7 @@ impl Scene { let mut dxf = DxfHatch::new(); dxf.is_solid = matches!( model.pattern, - crate::scene::hatch_model::HatchPattern::Solid + crate::scene::model::hatch_model::HatchPattern::Solid ); // The boundary points arrive in local render space (world_offset // already subtracted). The stored DXF entity must hold WCS, so add the @@ -4453,8 +4435,8 @@ impl Scene { let mut path = BoundaryPath::external(); path.add_edge(BoundaryEdge::Polyline(edge)); dxf.paths.push(path); - if let Some(entry) = crate::scene::hatch_patterns::find(&model.name) { - dxf.pattern = crate::scene::hatch_patterns::build_dxf_pattern(entry); + if let Some(entry) = crate::scene::model::hatch_patterns::find(&model.name) { + dxf.pattern = crate::scene::model::hatch_patterns::build_dxf_pattern(entry); } dxf.pattern_angle = model.angle_offset as f64; dxf.pattern_scale = if model.scale.abs() > 1e-6 { @@ -4768,7 +4750,7 @@ impl Scene { field: &str, ) -> Option { use crate::entities::traits::EntityTypeOps; - use crate::scene::object::PropValue; + use crate::scene::model::object::PropValue; match field { "layer" => Some(entity.common().layer.clone()), "color" => Some(Self::format_color(entity.common().color)), @@ -4992,7 +4974,7 @@ impl Scene { } for &h in handles { if let Some(entity) = self.document.get_entity_mut(h) { - dispatch::apply_transform(entity, t); + view::dispatch::apply_transform(entity, t); } if self.hatches.contains_key(&h) { let existing_color = self.hatches[&h].color; @@ -5048,12 +5030,12 @@ impl Scene { .collect(); let mut new_handles = Vec::with_capacity(clones.len()); for mut entity in clones { - dispatch::apply_transform(&mut entity, t); + view::dispatch::apply_transform(&mut entity, t); entity.common_mut().handle = Handle::NULL; let h = self.document.add_entity(entity).unwrap_or(Handle::NULL); if !h.is_null() { let new_model = if let Some(EntityType::Hatch(dxf)) = self.document.get_entity(h) { - let color = tess_util::aci_to_rgba(&dxf.common.color); + let color = convert::tess_util::aci_to_rgba(&dxf.common.color); Self::hatch_model_from_dxf(dxf, color, hatch_offset) } else { None @@ -5083,7 +5065,7 @@ impl Scene { .map(|p| [p.x, p.y, p.z]); if let Some(entity) = self.document.get_entity_mut(handle) { - dispatch::apply_grip(entity, grip_id, apply); + view::dispatch::apply_grip(entity, grip_id, apply); } // Translate MeshModel vertices by the same delta the grip applied. @@ -5121,7 +5103,7 @@ impl Scene { }; match self.document.get_entity(handle) { Some(EntityType::Hatch(dxf)) => { - let color = tess_util::aci_to_rgba(&dxf.common.color); + let color = convert::tess_util::aci_to_rgba(&dxf.common.color); if let Some(model) = Self::hatch_model_from_dxf(dxf, color, hatch_offset) { self.hatches.insert(handle, model); } else { @@ -5129,7 +5111,7 @@ impl Scene { } } Some(EntityType::Solid(solid)) => { - let color = tess_util::aci_to_rgba(&solid.common.color); + let color = convert::tess_util::aci_to_rgba(&solid.common.color); self.hatches .insert(handle, Self::solid_hatch_model(solid, color, hatch_offset)); } @@ -5262,7 +5244,7 @@ impl Scene { } else { vd.x.atan2(-vd.y) }; - let rotation = camera::yaw_pitch_to_quat(yaw, pitch, 0.0); + let rotation = view::camera::yaw_pitch_to_quat(yaw, pitch, 0.0); let view_right = rotation * glam::Vec3::X; let view_up = rotation * glam::Vec3::Y; let base = if model_space { @@ -5288,7 +5270,7 @@ impl Scene { cam.yaw = yaw; cam.pitch = pitch; cam.fov_y = fov_y; - cam.projection = camera::Projection::Orthographic; + cam.projection = view::camera::Projection::Orthographic; drop(cam); self.camera_generation += 1; true @@ -5350,7 +5332,7 @@ impl Scene { } else { vd.x.atan2(-vd.y) }; - let rotation = camera::yaw_pitch_to_quat(yaw, pitch, 0.0); + let rotation = view::camera::yaw_pitch_to_quat(yaw, pitch, 0.0); let view_right = rotation * glam::Vec3::X; let view_up = rotation * glam::Vec3::Y; // view_target is WCS; wire-space subtracts world_offset. @@ -5368,7 +5350,7 @@ impl Scene { rotation, distance, fov_y, - projection: camera::Projection::Orthographic, + projection: view::camera::Projection::Orthographic, yaw, pitch, }) @@ -5581,7 +5563,7 @@ impl Scene { } else { vd.x.atan2(-vd.y) }; - let rotation = camera::yaw_pitch_to_quat(yaw, pitch, 0.0); + let rotation = view::camera::yaw_pitch_to_quat(yaw, pitch, 0.0); let view_right = rotation * glam::Vec3::X; let view_up = rotation * glam::Vec3::Y; @@ -5604,7 +5586,7 @@ impl Scene { cam.yaw = yaw; cam.pitch = pitch; cam.fov_y = fov_y; - cam.projection = camera::Projection::Orthographic; + cam.projection = view::camera::Projection::Orthographic; drop(cam); self.camera_generation += 1; @@ -6387,8 +6369,8 @@ impl Scene { let mut sheet_cam = self.camera.borrow().clone(); sheet_cam.yaw = 0.0; sheet_cam.pitch = std::f32::consts::FRAC_PI_2; - sheet_cam.rotation = camera::yaw_pitch_to_quat(0.0, std::f32::consts::FRAC_PI_2, 0.0); - sheet_cam.projection = camera::Projection::Orthographic; + sheet_cam.rotation = view::camera::yaw_pitch_to_quat(0.0, std::f32::consts::FRAC_PI_2, 0.0); + sheet_cam.projection = view::camera::Projection::Orthographic; out.push(ViewportInstance { handle: Handle::NULL, tile_idx: None, @@ -6523,7 +6505,7 @@ impl Scene { let mut m = model.clone(); m.color = self.render_style(entity).0; if let EntityType::Hatch(dxf) = entity { - if let hatch_model::HatchPattern::Pattern(_) = &m.pattern { + if let model::hatch_model::HatchPattern::Pattern(_) = &m.pattern { m.angle_offset = dxf.pattern_angle as f32; m.scale = dxf.pattern_scale as f32; } @@ -6576,7 +6558,7 @@ impl Scene { } models.push(HatchModel { boundary: Arc::new(boundary), - pattern: hatch_model::HatchPattern::Solid, + pattern: model::hatch_model::HatchPattern::Solid, name: "WIPEOUT_FILL".into(), color: fill_color, angle_offset: 0.0, @@ -6592,7 +6574,7 @@ impl Scene { /// Build a Camera oriented and scaled to match a paper-space Viewport entity. /// Used by `active_viewports` to render model-space content through each /// content viewport's own view direction and scale. - fn camera_for_viewport(&self, vp_handle: Handle) -> Option { + fn camera_for_viewport(&self, vp_handle: Handle) -> Option { let vp = match self.document.get_entity(vp_handle) { Some(EntityType::Viewport(vp)) => vp, _ => return None, @@ -6615,7 +6597,7 @@ impl Scene { vd.x.atan2(-vd.y) }; - let rotation = camera::yaw_pitch_to_quat(yaw, pitch, 0.0); + let rotation = view::camera::yaw_pitch_to_quat(yaw, pitch, 0.0); // view_target is in raw model/WCS coords; the GPU renderer works in // wire-space (model - world_offset), so subtract world_offset here. @@ -6671,12 +6653,12 @@ impl Scene { // ortho_size = distance * tan(fov_y/2) => distance = view_height/2 / tan(fov_y/2) let distance = ((view_height / 2.0) / (fov_y * 0.5).tan()).max(0.001); - Some(camera::Camera { + Some(view::camera::Camera { target, rotation, distance, fov_y, - projection: camera::Projection::Orthographic, + projection: view::camera::Projection::Orthographic, yaw, pitch, }) @@ -6999,7 +6981,7 @@ fn tessellate_entity( bg_color: [f32; 4], anno_scale: f32, e: &EntityType, - block_cache: Option<&block_cache::BlockCache>, + block_cache: Option<&cache::block_cache::BlockCache>, // World-space XY view AABB (post `world_offset` subtraction). When // `Some`, entities whose AABB doesn't intersect this rect are skipped. view_aabb: Option<[f32; 4]>, @@ -7021,14 +7003,14 @@ fn tessellate_entity( let ab = entity_aabb(e, world_offset); if ab != WireModel::UNBOUNDED_AABB { if let Some(view) = view_aabb { - if block_cache::aabb_disjoint_xy(ab, view) { + if cache::block_cache::aabb_disjoint_xy(ab, view) { return vec![]; } } if let Some(wpp) = world_per_pixel { let w_px = (ab[2] - ab[0]).abs(); let h_px = (ab[3] - ab[1]).abs(); - // Keep in sync with `block_cache::MIN_PIXEL_SIZE`. + // Keep in sync with `cache::block_cache::MIN_PIXEL_SIZE`. // Text/MText have their own LOD ladder below // (baseline-line / greek / full) and must reach it // even when projected size is sub-5 px. @@ -7053,8 +7035,8 @@ fn tessellate_entity( // footprint doesn't drift when the camera // crosses the LOD threshold. See #19. let (entity_color, _, _, _, aci_idx) = - render::render_style_for(document, e); - let entity_color = render::adapt_to_bg(entity_color, bg_color); + view::render::render_style_for(document, e); + let entity_color = view::render::adapt_to_bg(entity_color, bg_color); if is_3d_entity { // `ab` is already in the local frame // (entity_aabb subtracted world_offset @@ -7116,7 +7098,7 @@ fn tessellate_entity( } else { (0.0_f32, [0.0f32; 8]) }; - let mut wires = tessellate::tessellate( + let mut wires = convert::tessellate::tessellate( document, h, e, @@ -7136,10 +7118,10 @@ fn tessellate_entity( } let (entity_color, pattern_length, pattern, line_weight_px, aci) = - render::render_style_for(document, e); - let entity_color = render::adapt_to_bg(entity_color, bg_color); + view::render::render_style_for(document, e); + let entity_color = view::render::adapt_to_bg(entity_color, bg_color); let lt_scale = document.header.linetype_scale as f32 * e.common().linetype_scale as f32; - let lt_name = render::linetype_name_for(document, e); + let lt_name = view::render::linetype_name_for(document, e); // PSLTSCALE: scale linetype dashes by viewport anno_scale so they appear uniform in paper space. let pslt_factor = if document.header.paper_space_linetype_scaling { anno_scale @@ -7315,8 +7297,8 @@ fn tessellate_entity( if let EntityType::Insert(ins) = e { // Resolve the INSERT's own style so ByBlock sub-entities can inherit it. - let (ins_color, ins_pat_len, ins_pat, ins_lw_px, _) = render::render_style_for(document, e); - let ins_color = render::adapt_to_bg(ins_color, bg_color); + let (ins_color, ins_pat_len, ins_pat, ins_lw_px, _) = view::render::render_style_for(document, e); + let ins_color = view::render::adapt_to_bg(ins_color, bg_color); let [ox, oy, oz] = world_offset; let ip = glam::Vec3::new( (ins.insert_point.x - ox) as f32, @@ -7332,7 +7314,7 @@ fn tessellate_entity( pattern_length: 0.0, pattern: [0.0; 8], line_weight_px: 1.0, - snap_pts: vec![(ip, wire_model::SnapHint::Insertion)], + snap_pts: vec![(ip, model::wire_model::SnapHint::Insertion)], tangent_geoms: vec![], key_vertices: vec![], aabb: WireModel::UNBOUNDED_AABB, @@ -7349,7 +7331,7 @@ fn tessellate_entity( .get(&ins.block_name) .map(|br| br.flags.is_xref || br.flags.is_xref_overlay) .unwrap_or(false); - if let Some(mut wires) = block_cache::expand_insert( + if let Some(mut wires) = cache::block_cache::expand_insert( cache, ins, h, @@ -7368,9 +7350,9 @@ fn tessellate_entity( // XCLIP: if this INSERT carries an enabled spatial filter, // clip the expanded block geometry to the boundary polygon so // only the portion inside the clip is drawn. - if let Some(sf) = xclip::insert_spatial_filter(document, ins) { - let poly = xclip::world_clip_polygon(sf, ins, world_offset); - xclip::clip_wires(&mut wires, &poly); + if let Some(sf) = pick::xclip::insert_spatial_filter(document, ins) { + let poly = pick::xclip::world_clip_polygon(sf, ins, world_offset); + pick::xclip::clip_wires(&mut wires, &poly); } // Per-INSERT attribute values. The block defn carries the @@ -7413,7 +7395,7 @@ fn tessellate_entity( .map(crate::modules::home::modify::explode::normalize_insert_entity) .flat_map(|sub| { let (sub_color, sub_pattern_length, sub_pattern, sub_line_weight_px, sub_aci) = - render::render_style_for_block_sub( + view::render::render_style_for_block_sub( document, &sub, ins_color, @@ -7421,16 +7403,16 @@ fn tessellate_entity( ins_pat, ins_lw_px, ); - let sub_color = render::adapt_to_bg(sub_color, bg_color); + let sub_color = view::render::adapt_to_bg(sub_color, bg_color); let sub_color = if is_xref && !sel { - block_cache::fade_toward_bg(sub_color, bg_color) + cache::block_cache::fade_toward_bg(sub_color, bg_color) } else { sub_color }; let sub_aabb = entity_aabb(&sub, world_offset); let sub_pattern_length = sub_pattern_length * pslt_factor; let sub_pattern = sub_pattern.map(|v| v * pslt_factor); - let mut wires = tessellate::tessellate( + let mut wires = convert::tessellate::tessellate( document, h, &sub, @@ -7591,7 +7573,7 @@ fn tessellate_entity( } } - let mut bases = tessellate::tessellate( + let mut bases = convert::tessellate::tessellate( document, h, e, @@ -7615,7 +7597,7 @@ fn tessellate_entity( // this path. if let Some(clt) = crate::linetypes::complex_lt(lt_name) { if let Some(base) = bases.first() { - let mut wires = complex_lt::apply_along( + let mut wires = text::complex_lt::apply_along( &base.name, &base.points, clt, diff --git a/src/scene/hatch_model.rs b/src/scene/model/hatch_model.rs similarity index 100% rename from src/scene/hatch_model.rs rename to src/scene/model/hatch_model.rs diff --git a/src/scene/hatch_patterns.rs b/src/scene/model/hatch_patterns.rs similarity index 98% rename from src/scene/hatch_patterns.rs rename to src/scene/model/hatch_patterns.rs index d1bb6ef13..44350a8b8 100644 --- a/src/scene/hatch_patterns.rs +++ b/src/scene/model/hatch_patterns.rs @@ -7,7 +7,7 @@ use std::sync::OnceLock; use crate::patterns::PatLineDef; -use crate::scene::hatch_model::{HatchPattern, PatFamily}; +use crate::scene::model::hatch_model::{HatchPattern, PatFamily}; use acadrust::entities::{HatchPattern as DxfPattern, HatchPatternLine}; use acadrust::types::Vector2; diff --git a/src/scene/image_model.rs b/src/scene/model/image_model.rs similarity index 100% rename from src/scene/image_model.rs rename to src/scene/model/image_model.rs diff --git a/src/scene/mesh_model.rs b/src/scene/model/mesh_model.rs similarity index 100% rename from src/scene/mesh_model.rs rename to src/scene/model/mesh_model.rs diff --git a/src/scene/model/mod.rs b/src/scene/model/mod.rs new file mode 100644 index 000000000..1fb423a65 --- /dev/null +++ b/src/scene/model/mod.rs @@ -0,0 +1,7 @@ +pub mod wire_model; +pub mod hatch_model; +pub mod hatch_patterns; +pub mod image_model; +pub mod mesh_model; +pub mod model_solid; +pub mod object; diff --git a/src/scene/model_solid.rs b/src/scene/model/model_solid.rs similarity index 97% rename from src/scene/model_solid.rs rename to src/scene/model/model_solid.rs index 57875a1a3..1e173c07d 100644 --- a/src/scene/model_solid.rs +++ b/src/scene/model/model_solid.rs @@ -8,7 +8,7 @@ use truck_modeling::{builder, Point3, Rad, Solid, Vector3, Wire}; -use crate::scene::mesh_model::{MeshLodSet, MeshModel}; +use crate::scene::model::mesh_model::{MeshLodSet, MeshModel}; const FULL: f64 = 7.0; // > 2π → builder closes the revolution @@ -99,7 +99,7 @@ pub fn torus_solid(center: [f64; 3], major: f64, minor: f64) -> Solid { /// fallback draws these as a wireframe over the shaded mesh, and hit-testing /// uses their points). pub fn edge_wires(solid: &Solid) -> Vec { - use crate::scene::truck_tess::{tessellate_edge, TruckTessResult}; + use crate::scene::convert::truck_tess::{tessellate_edge, TruckTessResult}; use acadrust::types::Vector3; let mut wires = Vec::new(); for shell in solid.boundaries() { @@ -151,7 +151,7 @@ pub fn boolean(op: Bool, a: &Solid, b: &Solid) -> Option { /// Tessellate a truck `Solid` into a single-LOD `MeshLodSet` (world-space, /// before world_offset is applied by the caller). pub fn mesh_from_solid(solid: &Solid, color: [f32; 4]) -> Option { - use crate::scene::truck_tess::{tessellate_solid, TruckTessResult}; + use crate::scene::convert::truck_tess::{tessellate_solid, TruckTessResult}; match tessellate_solid(solid, [0.0; 3]) { TruckTessResult::Mesh { verts, diff --git a/src/scene/object.rs b/src/scene/model/object.rs similarity index 100% rename from src/scene/object.rs rename to src/scene/model/object.rs diff --git a/src/scene/wire_model.rs b/src/scene/model/wire_model.rs similarity index 100% rename from src/scene/wire_model.rs rename to src/scene/model/wire_model.rs diff --git a/src/scene/grip.rs b/src/scene/pick/grip.rs similarity index 98% rename from src/scene/grip.rs rename to src/scene/pick/grip.rs index dfc2c24d5..b31684c53 100644 --- a/src/scene/grip.rs +++ b/src/scene/pick/grip.rs @@ -4,7 +4,7 @@ use acadrust::Handle; use glam::{Mat4, Vec3}; use iced::{Point, Rectangle}; -use super::object::{GripDef, GripShape}; +use crate::scene::model::object::{GripDef, GripShape}; /// Pixel radius for grip hit-detection. pub const GRIP_THRESHOLD_PX: f32 = 8.0; diff --git a/src/scene/hit_test.rs b/src/scene/pick/hit_test.rs similarity index 99% rename from src/scene/hit_test.rs rename to src/scene/pick/hit_test.rs index 97608d55c..6e9fcc985 100644 --- a/src/scene/hit_test.rs +++ b/src/scene/pick/hit_test.rs @@ -10,9 +10,9 @@ use acadrust::Handle; use glam::{Mat4, Vec3}; use iced::{Point, Rectangle}; -use super::hatch_model::HatchModel; -use super::mesh_model::MeshModel; -use super::wire_model::WireModel; +use crate::scene::model::hatch_model::HatchModel; +use crate::scene::model::mesh_model::MeshModel; +use crate::scene::model::wire_model::WireModel; /// Pixel radius used for single-click wire detection. const CLICK_THRESHOLD_PX: f32 = 8.0; diff --git a/src/scene/pick/mod.rs b/src/scene/pick/mod.rs new file mode 100644 index 000000000..03381292b --- /dev/null +++ b/src/scene/pick/mod.rs @@ -0,0 +1,5 @@ +pub mod hit_test; +pub mod selection; +pub mod grip; +pub mod quadtree; +pub mod xclip; diff --git a/src/scene/quadtree.rs b/src/scene/pick/quadtree.rs similarity index 100% rename from src/scene/quadtree.rs rename to src/scene/pick/quadtree.rs diff --git a/src/scene/selection.rs b/src/scene/pick/selection.rs similarity index 100% rename from src/scene/selection.rs rename to src/scene/pick/selection.rs diff --git a/src/scene/xclip.rs b/src/scene/pick/xclip.rs similarity index 99% rename from src/scene/xclip.rs rename to src/scene/pick/xclip.rs index d3f9f8441..033d20156 100644 --- a/src/scene/xclip.rs +++ b/src/scene/pick/xclip.rs @@ -15,7 +15,7 @@ use acadrust::objects::{ObjectType, SpatialFilter}; use acadrust::types::{Handle, Vector3}; use acadrust::CadDocument; -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; const NAN3: [f32; 3] = [f32::NAN, f32::NAN, f32::NAN]; @@ -113,7 +113,7 @@ pub fn clip_wires(wires: &mut Vec, poly: &[[f32; 2]]) { /// Clip a hatch fill boundary to `poly`. /// /// `boundary` is a hatch's NaN-separated loops in f32 offsets from -/// `world_origin` (the [`HatchModel`](crate::scene::hatch_model::HatchModel) +/// `world_origin` (the [`HatchModel`](crate::scene::model::hatch_model::HatchModel) /// representation); `poly` is the clip ring in the same world space the hatch /// occupies. Each loop is intersected with the clip polygon independently — /// the even-odd island structure is preserved because intersecting every loop diff --git a/src/scene/pipeline/face3d_gpu.rs b/src/scene/pipeline/face3d_gpu.rs index 7c5a163dc..c167ea1c8 100644 --- a/src/scene/pipeline/face3d_gpu.rs +++ b/src/scene/pipeline/face3d_gpu.rs @@ -18,7 +18,7 @@ // render pass send the 3D side through a depth-only pipeline for // HiddenLine while keeping the 2D side fully visible. -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; use iced::wgpu; use iced::wgpu::util::DeviceExt; diff --git a/src/scene/pipeline/hatch_batched_gpu.rs b/src/scene/pipeline/hatch_batched_gpu.rs index 1f5c94a51..086008ec2 100644 --- a/src/scene/pipeline/hatch_batched_gpu.rs +++ b/src/scene/pipeline/hatch_batched_gpu.rs @@ -35,7 +35,7 @@ // InstanceBuffer + Boundary + Family + Dash. Both stages share group // 1 with `read_only` access. -use crate::scene::hatch_model::{HatchModel, HatchPattern, PatFamily}; +use crate::scene::model::hatch_model::{HatchModel, HatchPattern, PatFamily}; use iced::wgpu; use iced::wgpu::util::DeviceExt; diff --git a/src/scene/pipeline/hatch_gpu.rs b/src/scene/pipeline/hatch_gpu.rs index 88e7bdc6f..4f788ed96 100644 --- a/src/scene/pipeline/hatch_gpu.rs +++ b/src/scene/pipeline/hatch_gpu.rs @@ -5,7 +5,7 @@ // binding 1 — BoundaryData (16384 bytes) boundary polygon vertices // binding 2 — FamilyBatchData (1296 bytes) up to 16 line families + 128 dash values -use crate::scene::hatch_model::{HatchModel, HatchPattern, PatFamily, MAX_HATCH_BOUNDARY_VERTS}; +use crate::scene::model::hatch_model::{HatchModel, HatchPattern, PatFamily, MAX_HATCH_BOUNDARY_VERTS}; use iced::wgpu; use iced::wgpu::util::DeviceExt; diff --git a/src/scene/pipeline/image_gpu.rs b/src/scene/pipeline/image_gpu.rs index 62af027ce..fbdddfa66 100644 --- a/src/scene/pipeline/image_gpu.rs +++ b/src/scene/pipeline/image_gpu.rs @@ -5,7 +5,7 @@ // binding 1 — sampler (bilinear filtering) // binding 2 — ImageParams (opacity uniform, 16 bytes) -use crate::scene::image_model::ImageModel; +use crate::scene::model::image_model::ImageModel; use iced::wgpu; use iced::wgpu::util::DeviceExt; diff --git a/src/scene/pipeline/mesh_gpu.rs b/src/scene/pipeline/mesh_gpu.rs index 5d83a52f5..6e0405f1a 100644 --- a/src/scene/pipeline/mesh_gpu.rs +++ b/src/scene/pipeline/mesh_gpu.rs @@ -7,7 +7,7 @@ // ------ // 40 B / vertex -use crate::scene::mesh_model::{MeshLodSet, MeshModel}; +use crate::scene::model::mesh_model::{MeshLodSet, MeshModel}; use iced::wgpu; use iced::wgpu::util::DeviceExt; diff --git a/src/scene/pipeline/mod.rs b/src/scene/pipeline/mod.rs index b475c0364..7b4dc62d5 100644 --- a/src/scene/pipeline/mod.rs +++ b/src/scene/pipeline/mod.rs @@ -19,10 +19,10 @@ pub use uniforms::Uniforms; pub use viewcube::ViewCubePipeline; pub use wire_gpu::WireGpu; -use crate::scene::hatch_model::HatchModel; -use crate::scene::image_model::ImageModel; -use crate::scene::mesh_model::MeshLodSet; -use crate::scene::wire_model::WireModel; +use crate::scene::model::hatch_model::HatchModel; +use crate::scene::model::image_model::ImageModel; +use crate::scene::model::mesh_model::MeshLodSet; +use crate::scene::model::wire_model::WireModel; /// MSAA sample count for the main drawing pipelines. const MSAA_SAMPLES: u32 = 4; diff --git a/src/scene/pipeline/uniforms.rs b/src/scene/pipeline/uniforms.rs index 248c09cde..6e2c07d58 100644 --- a/src/scene/pipeline/uniforms.rs +++ b/src/scene/pipeline/uniforms.rs @@ -1,4 +1,4 @@ -use crate::scene::camera::Camera; +use crate::scene::view::camera::Camera; use iced::Rectangle; #[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)] diff --git a/src/scene/pipeline/wire_gpu.rs b/src/scene/pipeline/wire_gpu.rs index 0aba6ba0e..afa1356de 100644 --- a/src/scene/pipeline/wire_gpu.rs +++ b/src/scene/pipeline/wire_gpu.rs @@ -22,7 +22,7 @@ // ------ // 76 B / instance -use crate::scene::wire_model::WireModel; +use crate::scene::model::wire_model::WireModel; use iced::wgpu; use rayon::prelude::*; diff --git a/src/scene/complex_lt.rs b/src/scene/text/complex_lt.rs similarity index 99% rename from src/scene/complex_lt.rs rename to src/scene/text/complex_lt.rs index f6c1eb4c7..ddafe71d8 100644 --- a/src/scene/complex_lt.rs +++ b/src/scene/text/complex_lt.rs @@ -8,8 +8,8 @@ use crate::entities::text_support::resolve_dxf_special_chars; use crate::linetypes::{ComplexLt, LtSegment}; -use crate::scene::lff; -use crate::scene::wire_model::WireModel; +use crate::scene::text::lff; +use crate::scene::model::wire_model::WireModel; // ── Public entry point ──────────────────────────────────────────────────── diff --git a/src/scene/font_face.rs b/src/scene/text/font_face.rs similarity index 98% rename from src/scene/font_face.rs rename to src/scene/text/font_face.rs index 843f1393c..5df7850fc 100644 --- a/src/scene/font_face.rs +++ b/src/scene/text/font_face.rs @@ -11,8 +11,8 @@ use std::ops::Deref; use std::sync::Arc; -use crate::scene::lff::{self, Glyph}; -use crate::scene::{sysfont, ttf_glyph}; +use crate::scene::text::lff::{self, Glyph}; +use crate::scene::text::{sysfont, ttf_glyph}; /// A glyph borrowed from a static LFF font or owned (cached `Arc`) from a TTF /// face. Derefs to [`Glyph`] either way. diff --git a/src/scene/lff.rs b/src/scene/text/lff.rs similarity index 93% rename from src/scene/lff.rs rename to src/scene/text/lff.rs index 0de82ff25..32e22da5b 100644 --- a/src/scene/lff.rs +++ b/src/scene/text/lff.rs @@ -24,32 +24,32 @@ use std::sync::{Mutex, OnceLock}; /// Every LibreCAD LFF font, keyed by its file stem (lower-case). Registered /// under the upper-cased stem and the font's `# Name:` header. const FONTS_SRC: &[(&str, &str)] = &[ - ("cyrillic_ii", include_str!("../../assets/fonts/cyrillic_ii.lff")), - ("gothgbt", include_str!("../../assets/fonts/gothgbt.lff")), - ("gothgrt", include_str!("../../assets/fonts/gothgrt.lff")), - ("gothitt", include_str!("../../assets/fonts/gothitt.lff")), - ("greekc", include_str!("../../assets/fonts/greekc.lff")), - ("greeks", include_str!("../../assets/fonts/greeks.lff")), - ("iso3098", include_str!("../../assets/fonts/iso3098.lff")), - ("iso", include_str!("../../assets/fonts/iso.lff")), - ("italicc", include_str!("../../assets/fonts/italicc.lff")), - ("italict", include_str!("../../assets/fonts/italict.lff")), - ("ltypeshp", include_str!("../../assets/fonts/ltypeshp.lff")), - ("romanc", include_str!("../../assets/fonts/romanc.lff")), - ("romand", include_str!("../../assets/fonts/romand.lff")), - ("romans", include_str!("../../assets/fonts/romans.lff")), - ("romant", include_str!("../../assets/fonts/romant.lff")), - ("scriptc", include_str!("../../assets/fonts/scriptc.lff")), - ("scripts", include_str!("../../assets/fonts/scripts.lff")), - ("simplex", include_str!("../../assets/fonts/simplex.lff")), - ("standard", include_str!("../../assets/fonts/standard.lff")), - ("syastro", include_str!("../../assets/fonts/syastro.lff")), - ("symap", include_str!("../../assets/fonts/symap.lff")), - ("symath", include_str!("../../assets/fonts/symath.lff")), - ("symbol", include_str!("../../assets/fonts/symbol.lff")), - ("symeteo", include_str!("../../assets/fonts/symeteo.lff")), - ("symusic", include_str!("../../assets/fonts/symusic.lff")), - ("unicode", include_str!("../../assets/fonts/unicode.lff")), + ("cyrillic_ii", include_str!("../../../assets/fonts/cyrillic_ii.lff")), + ("gothgbt", include_str!("../../../assets/fonts/gothgbt.lff")), + ("gothgrt", include_str!("../../../assets/fonts/gothgrt.lff")), + ("gothitt", include_str!("../../../assets/fonts/gothitt.lff")), + ("greekc", include_str!("../../../assets/fonts/greekc.lff")), + ("greeks", include_str!("../../../assets/fonts/greeks.lff")), + ("iso3098", include_str!("../../../assets/fonts/iso3098.lff")), + ("iso", include_str!("../../../assets/fonts/iso.lff")), + ("italicc", include_str!("../../../assets/fonts/italicc.lff")), + ("italict", include_str!("../../../assets/fonts/italict.lff")), + ("ltypeshp", include_str!("../../../assets/fonts/ltypeshp.lff")), + ("romanc", include_str!("../../../assets/fonts/romanc.lff")), + ("romand", include_str!("../../../assets/fonts/romand.lff")), + ("romans", include_str!("../../../assets/fonts/romans.lff")), + ("romant", include_str!("../../../assets/fonts/romant.lff")), + ("scriptc", include_str!("../../../assets/fonts/scriptc.lff")), + ("scripts", include_str!("../../../assets/fonts/scripts.lff")), + ("simplex", include_str!("../../../assets/fonts/simplex.lff")), + ("standard", include_str!("../../../assets/fonts/standard.lff")), + ("syastro", include_str!("../../../assets/fonts/syastro.lff")), + ("symap", include_str!("../../../assets/fonts/symap.lff")), + ("symath", include_str!("../../../assets/fonts/symath.lff")), + ("symbol", include_str!("../../../assets/fonts/symbol.lff")), + ("symeteo", include_str!("../../../assets/fonts/symeteo.lff")), + ("symusic", include_str!("../../../assets/fonts/symusic.lff")), + ("unicode", include_str!("../../../assets/fonts/unicode.lff")), ]; /// AutoCAD / DXF SHX font names → LFF stem. Names that already match a stem @@ -357,7 +357,7 @@ pub fn tessellate_text_run( return vec![]; } - let face = crate::scene::font_face::Face::resolve(font_name); + let face = crate::scene::text::font_face::Face::resolve(font_name); let scale = height / 9.0; let wf = if width_factor < 0.0 { width_factor.clamp(-100.0, -0.01) @@ -407,7 +407,7 @@ pub fn tessellate_text_run( return; } let family = ttf_family.unwrap_or(""); - if let Some(run) = crate::scene::ttf_glyph::shape_run(family, seg) { + if let Some(run) = crate::scene::text::ttf_glyph::shape_run(family, seg) { for g in &run.glyphs { emit_glyph(out, &g.strokes, *cursor_x); } diff --git a/src/scene/text/mod.rs b/src/scene/text/mod.rs new file mode 100644 index 000000000..5e04a77d2 --- /dev/null +++ b/src/scene/text/mod.rs @@ -0,0 +1,5 @@ +pub mod lff; +pub mod font_face; +pub mod sysfont; +pub mod ttf_glyph; +pub mod complex_lt; diff --git a/src/scene/sysfont.rs b/src/scene/text/sysfont.rs similarity index 100% rename from src/scene/sysfont.rs rename to src/scene/text/sysfont.rs diff --git a/src/scene/ttf_glyph.rs b/src/scene/text/ttf_glyph.rs similarity index 99% rename from src/scene/ttf_glyph.rs rename to src/scene/text/ttf_glyph.rs index 6258cf4b7..a3ff749c7 100644 --- a/src/scene/ttf_glyph.rs +++ b/src/scene/text/ttf_glyph.rs @@ -16,8 +16,8 @@ // boundary). Counters — the hole in "O" or "A" — come through as separate // closed contours; the wire renderer simply draws every contour. -use crate::scene::lff::Glyph; -use crate::scene::sysfont; +use crate::scene::text::lff::Glyph; +use crate::scene::text::sysfont; use rustc_hash::FxHashMap as HashMap; use std::sync::{Arc, Mutex, OnceLock}; diff --git a/src/scene/camera.rs b/src/scene/view/camera.rs similarity index 100% rename from src/scene/camera.rs rename to src/scene/view/camera.rs diff --git a/src/scene/dispatch.rs b/src/scene/view/dispatch.rs similarity index 94% rename from src/scene/dispatch.rs rename to src/scene/view/dispatch.rs index 94806ec23..29646ffdf 100644 --- a/src/scene/dispatch.rs +++ b/src/scene/view/dispatch.rs @@ -5,8 +5,8 @@ use acadrust::{EntityType, Handle}; use crate::command::EntityTransform; use crate::entities::traits::EntityTypeOps; -use crate::scene::object::{GripDef, PropSection}; -use crate::scene::properties; +use crate::scene::model::object::{GripDef, PropSection}; +use crate::scene::cache::properties; pub fn grips(entity: &EntityType) -> Vec { EntityTypeOps::grips(entity) @@ -71,7 +71,7 @@ pub fn apply_geom_prop(entity: &mut EntityType, field: &str, value: &str) { EntityTypeOps::apply_geom_prop(entity, field, value); } -pub fn apply_grip(entity: &mut EntityType, grip_id: usize, apply: crate::scene::object::GripApply) { +pub fn apply_grip(entity: &mut EntityType, grip_id: usize, apply: crate::scene::model::object::GripApply) { EntityTypeOps::apply_grip(entity, grip_id, apply); } diff --git a/src/scene/view/mod.rs b/src/scene/view/mod.rs new file mode 100644 index 000000000..54a51e1a7 --- /dev/null +++ b/src/scene/view/mod.rs @@ -0,0 +1,5 @@ +pub mod camera; +pub mod transform; +pub mod viewport_pane; +pub mod render; +pub mod dispatch; diff --git a/src/scene/render.rs b/src/scene/view/render.rs similarity index 94% rename from src/scene/render.rs rename to src/scene/view/render.rs index fc2a74f5b..01c14e34b 100644 --- a/src/scene/render.rs +++ b/src/scene/view/render.rs @@ -11,10 +11,10 @@ use iced::{Rectangle, Size}; use std::sync::Arc; -use super::pipeline::viewcube::{hover_id, VIEWCUBE_PX}; -use super::pipeline::MultiPipeline; -use super::tess_util; -use super::{HatchModel, ImageModel, MeshLodSet, Scene, Uniforms, ViewportInstance, WireModel}; +use crate::scene::pipeline::viewcube::{hover_id, VIEWCUBE_PX}; +use crate::scene::pipeline::MultiPipeline; +use crate::scene::convert::tess_util; +use crate::scene::{HatchModel, ImageModel, MeshLodSet, Scene, Uniforms, ViewportInstance, WireModel}; // ── Camera hover state (shader::Program::State) ─────────────────────────── @@ -31,85 +31,85 @@ pub struct CameraState { /// own inner `Pipeline` instance drawn into its own rectangle. #[derive(Debug)] pub struct ViewportData { - pub(super) wires: Arc>, + pub(in crate::scene) wires: Arc>, /// Live command-preview / interim / grip-drag overlay wires. Kept out of /// the main `wires` buffer so a drag re-uploads only this small set each /// frame, never the resident base buffer. Drawn on top in the wire pass. - pub(super) preview_wires: Arc>, + pub(in crate::scene) preview_wires: Arc>, /// 3DFACE entity wires — separated so they are uploaded to the dedicated /// face3d pipeline (fill + batched edges) instead of N individual WireGpu. - pub(super) face3d_wires: Arc>, + pub(in crate::scene) face3d_wires: Arc>, /// Per-entity normalized draw-order depth (handle.value() → (0,1)), used /// by the wire / face3d pipelines as a clip-z bias. WireModels carry no /// depth field (84 construction sites); the bias is looked up by handle /// at GPU-upload time from this map instead. - pub(super) draw_depths: Arc>, - pub(super) hatches: Arc>, + pub(in crate::scene) draw_depths: Arc>, + pub(in crate::scene) hatches: Arc>, /// Wipeout fills — rendered in a separate pass AFTER wires. - pub(super) wipeout_hatches: Arc>, - pub(super) images: Arc>, - pub(super) meshes: Arc>, - pub(super) uniforms: Uniforms, + pub(in crate::scene) wipeout_hatches: Arc>, + pub(in crate::scene) images: Arc>, + pub(in crate::scene) meshes: Arc>, + pub(in crate::scene) uniforms: Uniforms, /// Camera rotation matrix derived from the quaternion. /// Used by the ViewCube pipeline — no gimbal lock. - pub(super) cam_rotation: Mat4, - pub(super) hover_region: Option, - pub(super) show_viewcube: bool, + pub(in crate::scene) cam_rotation: Mat4, + pub(in crate::scene) hover_region: Option, + pub(in crate::scene) show_viewcube: bool, /// Header.fill_mode (FILLMODE): when false, hatch / wipeout / face3d-fill /// uploads short-circuit so the renderer draws only wireframe. - pub(super) fill_mode: bool, + pub(in crate::scene) fill_mode: bool, /// Per-view "Wireframe vs Solid" toggle. When `true`, 3D face fills /// are dropped on the upload path so 3D faces draw as edges only. /// Hatch / wipeout uploads are deliberately *not* gated by this flag — /// the user toggle should only affect 3D solids, not 2D fills. - pub(super) view_wireframe: bool, + pub(in crate::scene) view_wireframe: bool, /// Whether the active render mode wants 3D mesh fills uploaded. Off /// in `Wireframe2D` / `Wireframe3D`; on for every shaded variant. Set /// at the same point `view_wireframe` is computed so the two stay in /// lock-step for the gating logic in `prepare()`. - pub(super) mesh_fill: bool, + pub(in crate::scene) mesh_fill: bool, /// Whether the active render mode wants 3D mesh / face edges /// rendered on top of fills. Most shaded modes turn this off; the /// `*WithEdges` variants and the pure wireframes leave it on. - pub(super) show_3d_edges: bool, + pub(in crate::scene) show_3d_edges: bool, /// HiddenLine routes 3D fills through a depth-only prepass so edges /// occluded by closer geometry are culled by the LessEqual depth /// test on the wire passes that follow. - pub(super) hidden_line: bool, - pub(super) geometry_epoch: u64, + pub(in crate::scene) hidden_line: bool, + pub(in crate::scene) geometry_epoch: u64, /// Camera generation captured when this Primitive was assembled. Paired /// with `geometry_epoch` so the per-frame scissor / LOD recompute runs. - pub(super) camera_generation: u64, + pub(in crate::scene) camera_generation: u64, /// Content id of `wires` (Phase 3.2). Stable across a pure pan that reuses /// the Model-tile tessellation, so `prepare` skips re-uploading the /// world-space wire buffer when only the camera moved. Non-tile and /// preview/interim frames carry a fresh id each time → always re-upload. - pub(super) wire_content_id: u64, + pub(in crate::scene) wire_content_id: u64, /// `selected ∪ hover` handles for the GPU xray overlay. The highlight is no /// longer baked into the wire tessellation, so `prepare` rebuilds the /// selected-wire batch by filtering `wires` against this set. - pub(super) highlight_handles: Arc>, + pub(in crate::scene) highlight_handles: Arc>, /// Bumped on selection / hover change. Paired with `wire_content_id` to /// decide when the xray overlay batch needs rebuilding. - pub(super) selection_generation: u64, + pub(in crate::scene) selection_generation: u64, /// Signature of the *selected set* only (not hover). Gates the static-buffer /// re-upload (hatch tint, issue #71) so a hover doesn't re-upload every /// hatch / face3d buffer on hatch-heavy drawings. - pub(super) selected_sig: u64, + pub(in crate::scene) selected_sig: u64, /// Screen rectangle this viewport fills, **normalized** to the widget /// bounds (each component in 0..1). A single full-widget view is /// `(0, 0, 1, 1)`; tiled / floating viewports are sub-rectangles. /// Normalized form lets `render()` derive the physical sub-clip from /// the surface clip without needing the scale factor. - pub(super) screen_rect: Rectangle, + pub(in crate::scene) screen_rect: Rectangle, } #[derive(Debug)] pub struct Primitive { /// One entry per viewport drawn this frame (≥1). - pub(super) viewports: Vec, + pub(in crate::scene) viewports: Vec, /// Background color used to clear each viewport's MSAA buffer. - pub(super) bg_color: [f32; 4], + pub(in crate::scene) bg_color: [f32; 4], } /// Flags the render pipeline consumes, derived from @@ -428,7 +428,7 @@ fn crop_view_proj(view_proj: glam::Mat4, uo: f32, vo: f32, us: f32, vs: f32) -> impl Scene { /// Returns (entity_color, pattern_length, pattern, line_weight_px, aci). - pub(super) fn render_style(&self, e: &EntityType) -> ([f32; 4], f32, [f32; 8], f32, u8) { + pub(in crate::scene) fn render_style(&self, e: &EntityType) -> ([f32; 4], f32, [f32; 8], f32, u8) { let (color, pl, pat, lw, aci) = render_style_for(&self.document, e); let bg = if self.current_layout == "Model" { self.bg_color @@ -443,7 +443,7 @@ impl Scene { /// Resolves the effective linetype name for an entity, falling back to the /// layer's linetype when the entity's own linetype is "ByLayer". -pub(super) fn linetype_name_for<'a>(document: &'a CadDocument, e: &'a EntityType) -> &'a str { +pub(in crate::scene) fn linetype_name_for<'a>(document: &'a CadDocument, e: &'a EntityType) -> &'a str { let elt = &e.common().linetype; if elt.is_empty() || elt.eq_ignore_ascii_case("bylayer") { document @@ -458,7 +458,7 @@ pub(super) fn linetype_name_for<'a>(document: &'a CadDocument, e: &'a EntityType /// Returns `(entity_color, pattern_length, pattern, line_weight_px, aci)` for /// an entity, resolving ByLayer color and linetype from the document. -pub(super) fn render_style_for( +pub(in crate::scene) fn render_style_for( document: &CadDocument, e: &EntityType, ) -> ([f32; 4], f32, [f32; 8], f32, u8) { @@ -570,7 +570,7 @@ impl Scene { /// Model layout → one full-window viewport (more once tiled); paper /// layout → one viewport per floating content viewport. Each entry is /// rendered into its own screen rectangle by its own inner pipeline. - pub(super) fn build_viewports( + pub(in crate::scene) fn build_viewports( &self, bounds: Rectangle, model_render_mode: acadrust::entities::ViewportRenderMode, @@ -805,7 +805,7 @@ impl Scene { /// The cube draws in the top-right of the *active model tile* (which fills /// the canvas when there is a single tile), so the hover hit-test maps the /// cursor into that tile's local space and uses the tile's dimensions. - pub(super) fn update_viewcube_state( + pub(in crate::scene) fn update_viewcube_state( &self, state: &mut CameraState, bounds: Rectangle, @@ -828,7 +828,7 @@ impl Scene { } } - pub(super) fn viewcube_mouse_interaction(&self, state: &CameraState) -> mouse::Interaction { + pub(in crate::scene) fn viewcube_mouse_interaction(&self, state: &CameraState) -> mouse::Interaction { if state.hover_region.is_some() { mouse::Interaction::Pointer } else { diff --git a/src/scene/transform.rs b/src/scene/view/transform.rs similarity index 100% rename from src/scene/transform.rs rename to src/scene/view/transform.rs diff --git a/src/scene/viewport_pane.rs b/src/scene/view/viewport_pane.rs similarity index 99% rename from src/scene/viewport_pane.rs rename to src/scene/view/viewport_pane.rs index 5f5eded56..93f00e100 100644 --- a/src/scene/viewport_pane.rs +++ b/src/scene/view/viewport_pane.rs @@ -7,7 +7,7 @@ //! dedicated inner `Pipeline` (kept in the `MultiPipeline` outer). use super::render::{CameraState, Primitive}; -use super::Scene; +use crate::scene::Scene; use iced::widget::shader; use iced::{mouse, Event, Rectangle}; diff --git a/src/snap/mod.rs b/src/snap/mod.rs index b6e1781ee..0bed7f700 100644 --- a/src/snap/mod.rs +++ b/src/snap/mod.rs @@ -8,7 +8,7 @@ use glam::{Mat4, Vec3}; use iced::{Point, Rectangle}; use crate::command::TangentObject; -use crate::scene::wire_model::{SnapHint, TangentGeom, WireModel}; +use crate::scene::model::wire_model::{SnapHint, TangentGeom, WireModel}; use crate::ui::overlay::CROSSHAIR_ARM; // ── Snap type ───────────────────────────────────────────────────────────── diff --git a/src/ui/overlay.rs b/src/ui/overlay.rs index 982910071..552fe6310 100644 --- a/src/ui/overlay.rs +++ b/src/ui/overlay.rs @@ -6,7 +6,7 @@ use iced::widget::canvas; use iced::{Color, Element, Length, Point, Size, Theme}; use crate::app::Message; -use crate::scene::object::GripShape; +use crate::scene::model::object::GripShape; use crate::scene::SelectionState; /// Half-size of the crosshair center square in screen pixels (square = SQ*2 × SQ*2). @@ -421,7 +421,7 @@ impl canvas::Program for SelectionCanvas { // ── Grip markers ────────────────────────────────────────────────── for grip in &self.grips { let sp = grip.pos; - let h = crate::scene::grip::GRIP_HALF_PX; + let h = crate::scene::pick::grip::GRIP_HALF_PX; let path = match grip.shape { GripShape::Square => canvas::Path::rectangle( Point::new(sp.x - h, sp.y - h), diff --git a/src/ui/properties.rs b/src/ui/properties.rs index b4436dfc9..2ac5a78c1 100644 --- a/src/ui/properties.rs +++ b/src/ui/properties.rs @@ -22,7 +22,7 @@ const COMBO_PAD_V: f32 = (ROW_H - FONT_SZ * 1.3 - 2.0) / 2.0; // fills combo to const SWATCH_SZ: f32 = ROW_H * 0.54; // ≈14 px color swatch use crate::app::Message; -use crate::scene::object::{PropSection, PropValue}; +use crate::scene::model::object::{PropSection, PropValue}; const VARIES_LABEL: &str = "*VARIES*"; @@ -146,7 +146,7 @@ impl Default for PropertiesPanel { layer_combo: combo_box::State::new(vec![]), lineweight_combo: combo_box::State::new(lw_options()), linetype_combo: combo_box::State::new(vec![]), - hatch_pattern_combo: combo_box::State::new(crate::scene::hatch_patterns::names()), + hatch_pattern_combo: combo_box::State::new(crate::scene::model::hatch_patterns::names()), edit_buf: HashMap::default(), color_picker_open: false, color_palette_open: false, diff --git a/src/ui/textstyle.rs b/src/ui/textstyle.rs index 1ef307920..38fdee216 100644 --- a/src/ui/textstyle.rs +++ b/src/ui/textstyle.rs @@ -256,7 +256,7 @@ pub fn view_window<'a>(v: TextStyleView<'a>) -> Element<'a, Message> { }); // ── System TrueType fonts (read from the user's machine via fontdb) ── - let ttf_items: Vec> = crate::scene::sysfont::families() + let ttf_items: Vec> = crate::scene::text::sysfont::families() .iter() .map(|fam| { let is_sel = ttf_buf.eq_ignore_ascii_case(fam);