|
|
|
|
@ -1252,6 +1252,57 @@ class AutoRoutingTest(unittest.TestCase):
|
|
|
|
|
self.assertEqual(1, len(carriers))
|
|
|
|
|
self.assertEqual("UserPath", carriers[0].QetRouteCarrierKind)
|
|
|
|
|
|
|
|
|
|
def test_selected_points_object_can_be_used_as_user_path(self):
|
|
|
|
|
_install_fake_freecad()
|
|
|
|
|
terminal_objects, _wiring_objects, routing_network, _auto_routing = _reload_modules()
|
|
|
|
|
auto_routing_panel = importlib.import_module("AutoRoutingPanel")
|
|
|
|
|
app = sys.modules["FreeCAD"]
|
|
|
|
|
gui = sys.modules["FreeCADGui"]
|
|
|
|
|
doc = FakeDocument()
|
|
|
|
|
app.ActiveDocument = doc
|
|
|
|
|
terminal_objects.ensure_root_group(doc, "project-1")
|
|
|
|
|
route_path = doc.addObject("Part::Feature", "PointRoute")
|
|
|
|
|
route_path.Points = [
|
|
|
|
|
app.Vector(0, 0, 20),
|
|
|
|
|
app.Vector(40, 0, 20),
|
|
|
|
|
app.Vector(40, 30, 20),
|
|
|
|
|
]
|
|
|
|
|
gui.Selection = types.SimpleNamespace(
|
|
|
|
|
getSelection=lambda: [],
|
|
|
|
|
getSelectionEx=lambda: [FakeSelectionItem(obj=route_path)],
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
result = auto_routing_panel.AutoRoutingController().create_user_paths_from_selection()
|
|
|
|
|
carriers = routing_network.collect_route_carriers(doc)
|
|
|
|
|
|
|
|
|
|
self.assertEqual(1, result["user_path_carriers"])
|
|
|
|
|
self.assertEqual(
|
|
|
|
|
[(0.0, 0.0, 20.0), (40.0, 0.0, 20.0), (40.0, 30.0, 20.0)],
|
|
|
|
|
[(point.x, point.y, point.z) for point in carriers[0].Points],
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def test_selected_user_path_copies_source_capacity(self):
|
|
|
|
|
_install_fake_freecad()
|
|
|
|
|
terminal_objects, _wiring_objects, routing_network, _auto_routing = _reload_modules()
|
|
|
|
|
auto_routing_panel = importlib.import_module("AutoRoutingPanel")
|
|
|
|
|
app = sys.modules["FreeCAD"]
|
|
|
|
|
gui = sys.modules["FreeCADGui"]
|
|
|
|
|
doc = FakeDocument()
|
|
|
|
|
app.ActiveDocument = doc
|
|
|
|
|
terminal_objects.ensure_root_group(doc, "project-1")
|
|
|
|
|
route_path = doc.addObject("Part::Feature", "PointRoute")
|
|
|
|
|
route_path.Points = [app.Vector(0, 0, 20), app.Vector(100, 0, 20)]
|
|
|
|
|
route_path.QetRouteCarrierCapacity = 5
|
|
|
|
|
gui.Selection = types.SimpleNamespace(
|
|
|
|
|
getSelection=lambda: [],
|
|
|
|
|
getSelectionEx=lambda: [FakeSelectionItem(obj=route_path)],
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
auto_routing_panel.AutoRoutingController().create_user_paths_from_selection()
|
|
|
|
|
carrier = routing_network.collect_route_carriers(doc)[0]
|
|
|
|
|
|
|
|
|
|
self.assertEqual(5, carrier.QetRouteCarrierCapacity)
|
|
|
|
|
|
|
|
|
|
def test_controller_create_user_paths_reports_removed_stale_source_carriers(self):
|
|
|
|
|
_install_fake_freecad()
|
|
|
|
|
terminal_objects, _wiring_objects, routing_network, _auto_routing = _reload_modules()
|
|
|
|
|
@ -1693,6 +1744,120 @@ class AutoRoutingTest(unittest.TestCase):
|
|
|
|
|
self.assertIn("端子接入最大距离 1000.0 mm", message)
|
|
|
|
|
self.assertIn("补一段线槽/辅助路径", message)
|
|
|
|
|
|
|
|
|
|
def test_check_routing_path_network_warns_for_long_terminal_access(self):
|
|
|
|
|
_install_fake_freecad()
|
|
|
|
|
terminal_objects, _wiring_objects, routing_network, auto_routing = _reload_modules()
|
|
|
|
|
app = sys.modules["FreeCAD"]
|
|
|
|
|
doc = FakeDocument()
|
|
|
|
|
app.ActiveDocument = doc
|
|
|
|
|
terminal_objects.ensure_root_group(doc, "project-1")
|
|
|
|
|
_terminal(doc, terminal_objects, "TerminalLongAccess", "terminal-long-access", app.Vector(0, 0, 0))
|
|
|
|
|
routing_network.create_route_carrier(
|
|
|
|
|
doc,
|
|
|
|
|
[app.Vector(900, 0, 20), app.Vector(1000, 0, 20)],
|
|
|
|
|
project_uuid="project-1",
|
|
|
|
|
kind="WireDuct",
|
|
|
|
|
)
|
|
|
|
|
routing_network.create_terminal_access_carriers_from_document(
|
|
|
|
|
doc,
|
|
|
|
|
project_uuid="project-1",
|
|
|
|
|
terminal_exit_length=20.0,
|
|
|
|
|
max_distance=1000.0,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
result = auto_routing.check_eplan_routing_path_network(
|
|
|
|
|
doc,
|
|
|
|
|
project_uuid="project-1",
|
|
|
|
|
options={"terminal_access_max_distance": 1000.0},
|
|
|
|
|
)
|
|
|
|
|
diagnostic_group = doc.getObject("QETWiring_05_Diagnostics")
|
|
|
|
|
payload = json.loads(diagnostic_group.Group[0].QetDiagnosticJson)
|
|
|
|
|
message = auto_routing.format_routing_path_network_report(result["diagnostic"])
|
|
|
|
|
|
|
|
|
|
self.assertFalse(result["ok"])
|
|
|
|
|
self.assertEqual(1, len(payload["long_terminal_accesses"]))
|
|
|
|
|
self.assertEqual("terminal-long-access", payload["long_terminal_accesses"][0]["terminal_uuid"])
|
|
|
|
|
self.assertEqual(900.0, payload["long_terminal_accesses"][0]["terminal_access_length_mm"])
|
|
|
|
|
self.assertIn("端子接入过长", message)
|
|
|
|
|
self.assertIn("900.0 mm", message)
|
|
|
|
|
|
|
|
|
|
def test_check_routing_path_network_warns_for_invalid_terminal_local_route_points(self):
|
|
|
|
|
_install_fake_freecad()
|
|
|
|
|
terminal_objects, _wiring_objects, routing_network, auto_routing = _reload_modules()
|
|
|
|
|
app = sys.modules["FreeCAD"]
|
|
|
|
|
doc = FakeDocument()
|
|
|
|
|
app.ActiveDocument = doc
|
|
|
|
|
terminal_objects.ensure_root_group(doc, "project-1")
|
|
|
|
|
terminal = _terminal(doc, terminal_objects, "TerminalInvalidLocalPath", "terminal-invalid-local-path", app.Vector(0, 0, 0))
|
|
|
|
|
terminal.addProperty("App::PropertyString", "QetTerminalLocalRoutePointsJson", "QET Routing", "")
|
|
|
|
|
terminal.QetTerminalLocalRoutePointsJson = "{not-valid-json"
|
|
|
|
|
routing_network.create_route_carrier(
|
|
|
|
|
doc,
|
|
|
|
|
[app.Vector(0, 0, 20), app.Vector(100, 0, 20)],
|
|
|
|
|
project_uuid="project-1",
|
|
|
|
|
kind="WireDuct",
|
|
|
|
|
)
|
|
|
|
|
routing_network.create_terminal_access_carriers_from_document(
|
|
|
|
|
doc,
|
|
|
|
|
project_uuid="project-1",
|
|
|
|
|
terminal_exit_length=20.0,
|
|
|
|
|
max_distance=1000.0,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
result = auto_routing.check_eplan_routing_path_network(doc, project_uuid="project-1")
|
|
|
|
|
diagnostic_group = doc.getObject("QETWiring_05_Diagnostics")
|
|
|
|
|
payload = json.loads(diagnostic_group.Group[0].QetDiagnosticJson)
|
|
|
|
|
message = auto_routing.format_routing_path_network_report(result["diagnostic"])
|
|
|
|
|
|
|
|
|
|
self.assertFalse(result["ok"])
|
|
|
|
|
self.assertEqual(1, len(payload["invalid_terminal_local_routes"]))
|
|
|
|
|
self.assertEqual(
|
|
|
|
|
"terminal-invalid-local-path",
|
|
|
|
|
payload["invalid_terminal_local_routes"][0]["terminal_uuid"],
|
|
|
|
|
)
|
|
|
|
|
self.assertEqual(
|
|
|
|
|
"QetTerminalLocalRoutePointsJson",
|
|
|
|
|
payload["invalid_terminal_local_routes"][0]["property_name"],
|
|
|
|
|
)
|
|
|
|
|
self.assertIn("端子局部路径无效", message)
|
|
|
|
|
self.assertIn("terminal-invalid-local-path", message)
|
|
|
|
|
|
|
|
|
|
def test_check_routing_path_network_uses_terminal_local_route_end_for_connectivity(self):
|
|
|
|
|
_install_fake_freecad()
|
|
|
|
|
terminal_objects, _wiring_objects, routing_network, auto_routing = _reload_modules()
|
|
|
|
|
app = sys.modules["FreeCAD"]
|
|
|
|
|
doc = FakeDocument()
|
|
|
|
|
app.ActiveDocument = doc
|
|
|
|
|
terminal_objects.ensure_root_group(doc, "project-1")
|
|
|
|
|
terminal = _terminal(doc, terminal_objects, "TerminalLocalEndOnDuct", "terminal-local-end-on-duct", app.Vector(0, 0, 0))
|
|
|
|
|
terminal.addProperty("App::PropertyString", "QetTerminalLocalRoutePointsJson", "QET Routing", "")
|
|
|
|
|
terminal.QetTerminalLocalRoutePointsJson = json.dumps([[0, 0, 0], [1000, 0, 0]])
|
|
|
|
|
routing_network.create_route_carrier(
|
|
|
|
|
doc,
|
|
|
|
|
[app.Vector(1000, 0, 0), app.Vector(1100, 0, 0)],
|
|
|
|
|
project_uuid="project-1",
|
|
|
|
|
kind="WireDuct",
|
|
|
|
|
)
|
|
|
|
|
created = routing_network.create_terminal_access_carriers_from_document(
|
|
|
|
|
doc,
|
|
|
|
|
project_uuid="project-1",
|
|
|
|
|
terminal_exit_length=20.0,
|
|
|
|
|
max_distance=100.0,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
result = auto_routing.check_eplan_routing_path_network(
|
|
|
|
|
doc,
|
|
|
|
|
project_uuid="project-1",
|
|
|
|
|
options={"terminal_access_max_distance": 100.0},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
self.assertEqual([], created)
|
|
|
|
|
self.assertEqual([], result["diagnostic"]["unconnected_terminals"])
|
|
|
|
|
self.assertNotIn(
|
|
|
|
|
"unconnected_terminals",
|
|
|
|
|
[issue.get("code") for issue in result["diagnostic"]["issues"]],
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def test_format_routing_path_network_report_tolerates_malformed_samples(self):
|
|
|
|
|
_install_fake_freecad()
|
|
|
|
|
_terminal_objects, _wiring_objects, _routing_network, auto_routing = _reload_modules()
|
|
|
|
|
@ -1730,6 +1895,76 @@ class AutoRoutingTest(unittest.TestCase):
|
|
|
|
|
self.assertIn("(0.0, 0.0, 20.0)", message)
|
|
|
|
|
self.assertIn("补齐相邻线槽", message)
|
|
|
|
|
|
|
|
|
|
def test_check_routing_path_network_warns_when_network_is_empty(self):
|
|
|
|
|
_install_fake_freecad()
|
|
|
|
|
terminal_objects, _wiring_objects, _routing_network, auto_routing = _reload_modules()
|
|
|
|
|
doc = FakeDocument()
|
|
|
|
|
terminal_objects.ensure_root_group(doc, "project-1")
|
|
|
|
|
|
|
|
|
|
result = auto_routing.check_eplan_routing_path_network(doc, project_uuid="project-1")
|
|
|
|
|
diagnostic_group = doc.getObject("QETWiring_05_Diagnostics")
|
|
|
|
|
payload = json.loads(diagnostic_group.Group[0].QetDiagnosticJson)
|
|
|
|
|
message = auto_routing.format_routing_path_network_report(result["diagnostic"])
|
|
|
|
|
|
|
|
|
|
self.assertFalse(result["ok"])
|
|
|
|
|
self.assertEqual("empty_routing_path_network", payload["issues"][0]["code"])
|
|
|
|
|
self.assertEqual(0, payload["summary"]["segments"])
|
|
|
|
|
self.assertIn("布线路径网络为空", message)
|
|
|
|
|
|
|
|
|
|
def test_check_routing_path_network_warns_for_invalid_route_carrier_geometry(self):
|
|
|
|
|
_install_fake_freecad()
|
|
|
|
|
terminal_objects, _wiring_objects, routing_network, auto_routing = _reload_modules()
|
|
|
|
|
app = sys.modules["FreeCAD"]
|
|
|
|
|
doc = FakeDocument()
|
|
|
|
|
terminal_objects.ensure_root_group(doc, "project-1")
|
|
|
|
|
carrier = routing_network.create_route_carrier(
|
|
|
|
|
doc,
|
|
|
|
|
[app.Vector(0, 0, 20), app.Vector(100, 0, 20)],
|
|
|
|
|
label="坏用户路径",
|
|
|
|
|
project_uuid="project-1",
|
|
|
|
|
kind="UserPath",
|
|
|
|
|
)
|
|
|
|
|
carrier.Points = [app.Vector(0, 0, 20)]
|
|
|
|
|
|
|
|
|
|
result = auto_routing.check_eplan_routing_path_network(doc, project_uuid="project-1")
|
|
|
|
|
diagnostic_group = doc.getObject("QETWiring_05_Diagnostics")
|
|
|
|
|
payload = json.loads(diagnostic_group.Group[0].QetDiagnosticJson)
|
|
|
|
|
message = auto_routing.format_routing_path_network_report(result["diagnostic"])
|
|
|
|
|
|
|
|
|
|
self.assertFalse(result["ok"])
|
|
|
|
|
self.assertEqual(1, len(payload["invalid_route_carriers"]))
|
|
|
|
|
self.assertEqual("UserPath", payload["invalid_route_carriers"][0]["carrier"]["kind"])
|
|
|
|
|
self.assertEqual(1, payload["invalid_route_carriers"][0]["point_count"])
|
|
|
|
|
self.assertIn("路径对象几何无效", message)
|
|
|
|
|
self.assertIn("坏用户路径", message)
|
|
|
|
|
|
|
|
|
|
def test_check_routing_path_network_warns_when_only_routing_range_is_available(self):
|
|
|
|
|
_install_fake_freecad()
|
|
|
|
|
terminal_objects, _wiring_objects, routing_network, auto_routing = _reload_modules()
|
|
|
|
|
app = sys.modules["FreeCAD"]
|
|
|
|
|
doc = FakeDocument()
|
|
|
|
|
terminal_objects.ensure_root_group(doc, "project-1")
|
|
|
|
|
routing_network.create_route_carrier(
|
|
|
|
|
doc,
|
|
|
|
|
[app.Vector(0, 0, 20), app.Vector(100, 0, 20)],
|
|
|
|
|
project_uuid="project-1",
|
|
|
|
|
kind="RoutingRange",
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
result = auto_routing.check_eplan_routing_path_network(doc, project_uuid="project-1")
|
|
|
|
|
diagnostic_group = doc.getObject("QETWiring_05_Diagnostics")
|
|
|
|
|
payload = json.loads(diagnostic_group.Group[0].QetDiagnosticJson)
|
|
|
|
|
message = auto_routing.format_routing_path_network_report(result["diagnostic"])
|
|
|
|
|
|
|
|
|
|
self.assertFalse(result["ok"])
|
|
|
|
|
self.assertEqual(1, payload["routing_range_only_network"]["routing_range_carriers"])
|
|
|
|
|
self.assertEqual(
|
|
|
|
|
0,
|
|
|
|
|
payload["routing_range_only_network"]["primary_route_carriers"],
|
|
|
|
|
)
|
|
|
|
|
self.assertIn("routing_range_only_network", [issue.get("code") for issue in payload["issues"]])
|
|
|
|
|
self.assertIn("仅使用布线面兜底", message)
|
|
|
|
|
|
|
|
|
|
def test_format_routing_path_network_report_includes_bridged_segment_count(self):
|
|
|
|
|
_install_fake_freecad()
|
|
|
|
|
_terminal_objects, _wiring_objects, _routing_network, auto_routing = _reload_modules()
|
|
|
|
|
@ -2692,6 +2927,47 @@ class AutoRoutingTest(unittest.TestCase):
|
|
|
|
|
self.assertEqual("wire-a", diagnostic_payload["route_samples"][0]["wire_uuid"])
|
|
|
|
|
self.assertEqual("Routed", diagnostic_payload["route_samples"][0]["route_status"])
|
|
|
|
|
|
|
|
|
|
def test_route_eplan_connections_batch_diagnostic_includes_quality_warnings(self):
|
|
|
|
|
_install_fake_freecad()
|
|
|
|
|
terminal_objects, _wiring_objects, routing_network, auto_routing = _reload_modules()
|
|
|
|
|
app = sys.modules["FreeCAD"]
|
|
|
|
|
doc = FakeDocument()
|
|
|
|
|
terminal_objects.ensure_root_group(doc, "project-1")
|
|
|
|
|
_terminal(doc, terminal_objects, "TerminalStart", "terminal-start", app.Vector(0, 0, 0))
|
|
|
|
|
_terminal(doc, terminal_objects, "TerminalEnd", "terminal-end", app.Vector(100, 0, 0))
|
|
|
|
|
routing_network.create_route_carrier(
|
|
|
|
|
doc,
|
|
|
|
|
[app.Vector(0, 0, 20), app.Vector(100, 0, 20)],
|
|
|
|
|
project_uuid="project-1",
|
|
|
|
|
kind="RoutingRange",
|
|
|
|
|
)
|
|
|
|
|
payload = {
|
|
|
|
|
"project_uuid": "project-1",
|
|
|
|
|
"wires": [
|
|
|
|
|
{
|
|
|
|
|
"wire_id": "wire-surface",
|
|
|
|
|
"wire_label": "N-SURFACE",
|
|
|
|
|
"start_terminal_uuid": "terminal-start",
|
|
|
|
|
"end_terminal_uuid": "terminal-end",
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
report = auto_routing.route_eplan_connections_from_payload(doc, payload)
|
|
|
|
|
diagnostic_group = doc.getObject("QETWiring_05_Diagnostics")
|
|
|
|
|
diagnostic_payload = json.loads(diagnostic_group.Group[0].QetDiagnosticJson)
|
|
|
|
|
|
|
|
|
|
self.assertEqual(1, report["routed"])
|
|
|
|
|
self.assertEqual(1, diagnostic_payload["route_quality_warning_count"])
|
|
|
|
|
self.assertEqual(
|
|
|
|
|
"wire-surface",
|
|
|
|
|
diagnostic_payload["route_quality_warning_samples"][0]["wire_uuid"],
|
|
|
|
|
)
|
|
|
|
|
self.assertEqual(
|
|
|
|
|
["RoutingRange"],
|
|
|
|
|
diagnostic_payload["route_quality_warning_samples"][0]["carrier_kinds"],
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def test_route_eplan_connections_reports_total_connection_route_length(self):
|
|
|
|
|
_install_fake_freecad()
|
|
|
|
|
terminal_objects, _wiring_objects, routing_network, auto_routing = _reload_modules()
|
|
|
|
|
@ -3108,6 +3384,49 @@ class AutoRoutingTest(unittest.TestCase):
|
|
|
|
|
self.assertEqual(1, route["network"]["carriers"])
|
|
|
|
|
self.assertEqual("WireDuct", route["route_track"]["segments"][0]["carrier"]["kind"])
|
|
|
|
|
|
|
|
|
|
def test_route_eplan_connections_report_includes_routing_path_network_diagnostic(self):
|
|
|
|
|
_install_fake_freecad()
|
|
|
|
|
terminal_objects, _wiring_objects, routing_network, auto_routing = _reload_modules()
|
|
|
|
|
app = sys.modules["FreeCAD"]
|
|
|
|
|
doc = FakeDocument()
|
|
|
|
|
terminal_objects.ensure_root_group(doc, "project-1")
|
|
|
|
|
_terminal(doc, terminal_objects, "TerminalStart", "terminal-start", app.Vector(0, 0, 0))
|
|
|
|
|
_terminal(doc, terminal_objects, "TerminalEnd", "terminal-end", app.Vector(100, 0, 0))
|
|
|
|
|
routing_network.create_route_carrier(
|
|
|
|
|
doc,
|
|
|
|
|
[app.Vector(0, 0, 20), app.Vector(100, 0, 20)],
|
|
|
|
|
project_uuid="project-1",
|
|
|
|
|
kind="RoutingRange",
|
|
|
|
|
)
|
|
|
|
|
payload = {
|
|
|
|
|
"project_uuid": "project-1",
|
|
|
|
|
"wires": [
|
|
|
|
|
{
|
|
|
|
|
"wire_id": "wire-range-only",
|
|
|
|
|
"wire_label": "N-RANGE",
|
|
|
|
|
"start_terminal_uuid": "terminal-start",
|
|
|
|
|
"end_terminal_uuid": "terminal-end",
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
report = auto_routing.route_eplan_connections(
|
|
|
|
|
doc,
|
|
|
|
|
payload=payload,
|
|
|
|
|
options={"hide_route_carriers_after_route": False},
|
|
|
|
|
project_uuid="project-1",
|
|
|
|
|
)
|
|
|
|
|
message = auto_routing.format_eplan_connection_route_report(report)
|
|
|
|
|
|
|
|
|
|
self.assertEqual(1, report["routed"])
|
|
|
|
|
self.assertFalse(report["routing_path_network_diagnostic"]["ok"])
|
|
|
|
|
self.assertIn(
|
|
|
|
|
"routing_range_only_network",
|
|
|
|
|
report["routing_path_network_diagnostic"]["issue_codes"],
|
|
|
|
|
)
|
|
|
|
|
self.assertIn("路径网络检查提示", message)
|
|
|
|
|
self.assertIn("仅使用布线面兜底", message)
|
|
|
|
|
|
|
|
|
|
def test_route_eplan_connections_preserves_endpoint_metadata_on_routed_wire(self):
|
|
|
|
|
_install_fake_freecad()
|
|
|
|
|
terminal_objects, _wiring_objects, routing_network, auto_routing = _reload_modules()
|
|
|
|
|
|