brep_render/engine_state/
wire_harness_ops.rs1use super::*;
2use brep_kernel::{WireHarnessConnection, WireHarnessReport, WireHarnessState};
3
4#[derive(Debug, Default, Clone, PartialEq)]
7pub struct ConnectionPatch {
8 pub name: Option<String>,
9 pub from: Option<String>,
10 pub to: Option<String>,
11 pub diameter: Option<f64>,
12}
13
14impl EngineState {
15 pub fn wire_harness_report(&self) -> Option<&WireHarnessReport> {
21 self.wire_harness_report.as_ref()
22 }
23
24 pub fn wire_harness_state(&self) -> WireHarnessState {
27 self.history
28 .wire_harness_block()
29 .and_then(|block| serde_json::from_value(block.clone()).ok())
30 .unwrap_or_default()
31 }
32
33 pub fn wire_harness_state_json(&self) -> String {
36 let state = self.wire_harness_state();
37 serde_json::json!({
38 "connections": state.connections,
39 "buildBundles": state.build_bundles,
40 "report": self.wire_harness_report,
41 })
42 .to_string()
43 }
44
45 fn write_wire_harness_state(&mut self, state: WireHarnessState) -> String {
52 let block = if state.connections.is_empty() && state.id_counter == 0 {
53 None
54 } else {
55 serde_json::to_value(&state).ok()
56 };
57 self.history.set_wire_harness_block(block);
58 self.rerun_history()
59 }
60
61 pub fn wire_harness_add_connection(&mut self, from: &str, to: &str, diameter: f64) -> String {
64 let mut state = self.wire_harness_state();
65 let id = state.next_id();
66 let name = format!("Wire {}", state.id_counter);
67 state.connections.push(WireHarnessConnection {
68 id: id.clone(),
69 name,
70 from: from.to_string(),
71 to: to.to_string(),
72 diameter: if diameter.is_finite() && diameter > 0.0 { diameter } else { 1.0 },
73 });
74 self.write_wire_harness_state(state);
75 id
76 }
77
78 pub fn wire_harness_update_connection(
81 &mut self,
82 id: &str,
83 patch: &ConnectionPatch,
84 ) -> Result<(), String> {
85 let mut state = self.wire_harness_state();
86 let connection = state
87 .connections
88 .iter_mut()
89 .find(|connection| connection.id == id)
90 .ok_or_else(|| format!("no harness connection '{id}'"))?;
91 if let Some(name) = &patch.name {
92 connection.name = name.trim().to_string();
93 }
94 if let Some(from) = &patch.from {
95 connection.from = from.trim().to_string();
96 }
97 if let Some(to) = &patch.to {
98 connection.to = to.trim().to_string();
99 }
100 if let Some(diameter) = patch.diameter {
101 if !(diameter.is_finite() && diameter > 0.0) {
102 return Err(format!("wire diameter must be positive, got {diameter}"));
103 }
104 connection.diameter = diameter;
105 }
106 self.write_wire_harness_state(state);
107 Ok(())
108 }
109
110 pub fn wire_harness_remove_connection(&mut self, id: &str) -> Result<(), String> {
112 let mut state = self.wire_harness_state();
113 let before = state.connections.len();
114 state.connections.retain(|connection| connection.id != id);
115 if state.connections.len() == before {
116 return Err(format!("no harness connection '{id}'"));
117 }
118 self.write_wire_harness_state(state);
119 Ok(())
120 }
121
122 pub fn wire_harness_set_build_bundles(&mut self, on: bool) {
124 let mut state = self.wire_harness_state();
125 if state.build_bundles == on {
126 return;
127 }
128 state.build_bundles = on;
129 self.write_wire_harness_state(state);
130 }
131
132 pub fn wire_harness_hover_connection(&mut self, id: &str) {
138 let state = self.wire_harness_state();
139 let mut names: Vec<String> = Vec::new();
140 if let Some(connection) = state.connections.iter().find(|c| c.id == id) {
141 for port in [&connection.from, &connection.to] {
142 if !port.is_empty() && self.scene.solid(port).is_some() {
143 names.push(port.clone());
144 }
145 }
146 }
147 if let Some(report) = &self.wire_harness_report {
148 if let Some(route) = report.routes.iter().find(|route| route.connection_id == id) {
149 for segment in &route.segment_ids {
150 if let Some(bundle) = report.bundles.iter().find(|b| &b.segment_id == segment) {
151 if !bundle.solid_name.is_empty() {
152 names.push(bundle.solid_name.clone());
153 }
154 }
155 }
156 }
157 }
158 self.clear_hover();
159 self.emphasis.hovered_solids.extend(names);
160 self.emphasis.generation = self.emphasis.generation.wrapping_add(1);
161 self.dirty = true;
162 }
163
164 pub fn wire_harness_hover_end(&mut self) {
166 if self.clear_hover() {
167 self.dirty = true;
168 }
169 }
170}
171
172