Storm Sewer: interactive in-app network — snapping, tracked objects, analyze the drawing
Replaces the .ssn-file workflow with an interactive one driven by the canvas: - Structures (SS_INLET / SS_JUNCTION / SS_OUTFALL) prompt invert/rim/area/C on the command line and commit a CIRCLE tagged with STORMSEWER_STRUCT XDATA [kind, invert, rim, area, C]. Outfalls skip area/C. - SS_PIPE picks a START and END structure (entity-pick), snapping its endpoints to their centers, prompts diameter/n, and stores connectivity (the two structure handles) in STORMSEWER_PIPE XDATA [diameter, n, from, to]. - SS_ANALYZE / SS_REPORT / SS_PROFILE rebuild the network from the drawn entities (data.rs::network_from_entities) and analyze it directly; SS_ANALYZE overlays flow/HGL labels without redrawing the geometry. Because the data lives on the entities as XDATA, the network round-trips to DWG/DXF. One additive line in src/app/update.rs adds SS_PIPE to the inject_picked_entity allow-list so the command can read the picked structure's center for snapping. 15 module tests cover the XDATA round-trip, analyze-from-drawing, and the command step machines. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9b44eb6400
commit
1e68219b43
7 changed files with 609 additions and 104 deletions
|
|
@ -7,6 +7,7 @@
|
|||
// INTEGRATION.md for where each `SS_*` command plugs in.
|
||||
|
||||
pub mod analysis;
|
||||
pub mod data;
|
||||
pub mod structures;
|
||||
|
||||
use crate::modules::{CadModule, IconKind, ModuleEvent, RibbonGroup, RibbonItem, ToolDef};
|
||||
|
|
@ -156,4 +157,38 @@ PIPE P2 N2 OUT 300 1.5 0.013
|
|||
let err = super::analysis::analyze_text("NODE X inlet 0 0 oops 1 1 1").unwrap_err();
|
||||
assert!(err.contains("line 1"), "{err}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn analyze_doc_runs_on_drawn_network() {
|
||||
use acadrust::types::Vector3;
|
||||
use acadrust::{Circle, EntityType, Handle, Line};
|
||||
use stormsewer::network::NodeKind;
|
||||
|
||||
let mk_struct = |h: u64, kind, x: f64, inv: f64| {
|
||||
let mut e = EntityType::Circle(Circle {
|
||||
center: Vector3::new(x, 0.0, 0.0),
|
||||
radius: 3.0,
|
||||
..Default::default()
|
||||
});
|
||||
e.common_mut().handle = Handle::new(h);
|
||||
e.common_mut()
|
||||
.extended_data
|
||||
.add_record(super::data::structure_xdata(kind, inv, inv + 6.0, 1.0, 0.7));
|
||||
e
|
||||
};
|
||||
let mut pipe =
|
||||
EntityType::Line(Line::from_points(Vector3::new(0.0, 0.0, 0.0), Vector3::new(200.0, 0.0, 0.0)));
|
||||
pipe.common_mut()
|
||||
.extended_data
|
||||
.add_record(super::data::pipe_xdata(1.5, 0.013, Handle::new(1), Handle::new(2)));
|
||||
let ents = vec![
|
||||
mk_struct(1, NodeKind::Inlet, 0.0, 104.0),
|
||||
mk_struct(2, NodeKind::Outfall, 200.0, 100.0),
|
||||
pipe,
|
||||
];
|
||||
|
||||
let (annotations, report) = super::analysis::analyze_doc(ents.iter()).expect("analyze drawn net");
|
||||
assert!(!annotations.is_empty(), "expected flow/HGL labels");
|
||||
assert!(report.contains("STORM SEWER ANALYSIS"), "report:\n{report}");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue