|
|
|
@ -662,6 +662,57 @@ class AutoRoutingTest(unittest.TestCase):
|
|
|
|
self.assertEqual((0.65, 0.2, 1.0), terminal_access.ViewObject.LineColor)
|
|
|
|
self.assertEqual((0.65, 0.2, 1.0), terminal_access.ViewObject.LineColor)
|
|
|
|
self.assertEqual("Solid", terminal_access.ViewObject.DrawStyle)
|
|
|
|
self.assertEqual("Solid", terminal_access.ViewObject.DrawStyle)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_set_route_carriers_visibility_toggles_only_route_helpers(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, 0), app.Vector(100, 0, 0)],
|
|
|
|
|
|
|
|
project_uuid="project-1",
|
|
|
|
|
|
|
|
kind="WireDuct",
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
device = doc.addObject("Part::Feature", "DeviceA")
|
|
|
|
|
|
|
|
device.ViewObject.Visibility = True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
hidden = routing_network.set_route_carriers_visibility(doc, False)
|
|
|
|
|
|
|
|
self.assertFalse(carrier.ViewObject.Visibility)
|
|
|
|
|
|
|
|
shown = routing_network.set_route_carriers_visibility(doc, True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.assertEqual(1, hidden)
|
|
|
|
|
|
|
|
self.assertEqual(1, shown)
|
|
|
|
|
|
|
|
self.assertTrue(carrier.ViewObject.Visibility)
|
|
|
|
|
|
|
|
self.assertTrue(device.ViewObject.Visibility)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_collect_route_carriers_ignores_deleted_object_references(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, 0), app.Vector(100, 0, 0)],
|
|
|
|
|
|
|
|
project_uuid="project-1",
|
|
|
|
|
|
|
|
kind="WireDuct",
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DeletedObjectReference:
|
|
|
|
|
|
|
|
Name = "DeletedCarrier"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __getattr__(self, name):
|
|
|
|
|
|
|
|
if name == "QetRoutingRole":
|
|
|
|
|
|
|
|
raise RuntimeError("Cannot access attribute 'QetRoutingRole' of deleted object")
|
|
|
|
|
|
|
|
raise AttributeError(name)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
doc.Objects.append(DeletedObjectReference())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
carriers = routing_network.collect_route_carriers(doc)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.assertEqual([carrier], carriers)
|
|
|
|
|
|
|
|
|
|
|
|
def test_route_carrier_exposes_capacity_property_for_auto_routing(self):
|
|
|
|
def test_route_carrier_exposes_capacity_property_for_auto_routing(self):
|
|
|
|
_install_fake_freecad()
|
|
|
|
_install_fake_freecad()
|
|
|
|
terminal_objects, _wiring_objects, routing_network, _auto_routing = _reload_modules()
|
|
|
|
terminal_objects, _wiring_objects, routing_network, _auto_routing = _reload_modules()
|
|
|
|
@ -1141,6 +1192,182 @@ class AutoRoutingTest(unittest.TestCase):
|
|
|
|
self.assertEqual(1, result["wire_duct_carriers"])
|
|
|
|
self.assertEqual(1, result["wire_duct_carriers"])
|
|
|
|
self.assertEqual("selection", result["source_mode"])
|
|
|
|
self.assertEqual("selection", result["source_mode"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_generate_routing_paths_uses_selected_route_path_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", "UserRouteSketch")
|
|
|
|
|
|
|
|
route_path.Label = "用户主路径A"
|
|
|
|
|
|
|
|
route_path.Shape = FakeShape(
|
|
|
|
|
|
|
|
FakeBoundBox(0, 100, 0, 80, 20, 20),
|
|
|
|
|
|
|
|
edges=[
|
|
|
|
|
|
|
|
FakeEdge(app.Vector(0, 0, 20), app.Vector(0, 80, 20)),
|
|
|
|
|
|
|
|
FakeEdge(app.Vector(0, 80, 20), app.Vector(100, 80, 20)),
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
gui.Selection = types.SimpleNamespace(
|
|
|
|
|
|
|
|
getSelection=lambda: [],
|
|
|
|
|
|
|
|
getSelectionEx=lambda: [FakeSelectionItem(obj=route_path)],
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
result = auto_routing_panel.AutoRoutingController().generate_routing_paths()
|
|
|
|
|
|
|
|
carriers = routing_network.collect_route_carriers(doc)
|
|
|
|
|
|
|
|
user_paths = [item for item in carriers if item.QetRouteCarrierKind == "UserPath"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.assertEqual(1, result["user_path_carriers"])
|
|
|
|
|
|
|
|
self.assertEqual(1, len(user_paths))
|
|
|
|
|
|
|
|
self.assertEqual("UserRouteSketch", user_paths[0].QetRouteSourceName)
|
|
|
|
|
|
|
|
self.assertEqual("用户主路径A", user_paths[0].QetRouteSourceLabel)
|
|
|
|
|
|
|
|
self.assertEqual("selection", result["source_mode"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_controller_creates_selected_user_paths_without_full_network_generation(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", "UserRouteSketch")
|
|
|
|
|
|
|
|
route_path.Shape = FakeShape(
|
|
|
|
|
|
|
|
FakeBoundBox(0, 100, 0, 80, 20, 20),
|
|
|
|
|
|
|
|
edges=[FakeEdge(app.Vector(0, 0, 20), app.Vector(100, 0, 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(1, result["network"]["kinds"]["UserPath"])
|
|
|
|
|
|
|
|
self.assertEqual(1, len(carriers))
|
|
|
|
|
|
|
|
self.assertEqual("UserPath", carriers[0].QetRouteCarrierKind)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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()
|
|
|
|
|
|
|
|
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", "UserRouteSketch")
|
|
|
|
|
|
|
|
route_path.Shape = FakeShape(
|
|
|
|
|
|
|
|
FakeBoundBox(0, 100, 0, 80, 20, 20),
|
|
|
|
|
|
|
|
edges=[FakeEdge(app.Vector(0, 0, 20), app.Vector(100, 0, 20))],
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
gui.Selection = types.SimpleNamespace(
|
|
|
|
|
|
|
|
getSelection=lambda: [],
|
|
|
|
|
|
|
|
getSelectionEx=lambda: [FakeSelectionItem(obj=route_path)],
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
auto_routing_panel.AutoRoutingController().create_user_paths_from_selection()
|
|
|
|
|
|
|
|
doc.removeObject("UserRouteSketch")
|
|
|
|
|
|
|
|
gui.Selection = types.SimpleNamespace(
|
|
|
|
|
|
|
|
getSelection=lambda: [],
|
|
|
|
|
|
|
|
getSelectionEx=lambda: [],
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
result = auto_routing_panel.AutoRoutingController().create_user_paths_from_selection()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.assertEqual(1, result["removed_stale_carriers"])
|
|
|
|
|
|
|
|
self.assertEqual(0, result["network"]["carriers"])
|
|
|
|
|
|
|
|
self.assertEqual([], routing_network.collect_route_carriers(doc))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_terminal_access_uses_terminal_local_route_points_before_main_network(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 = _terminal(doc, terminal_objects, "TerminalStart", "terminal-start", app.Vector(0, 0, 0))
|
|
|
|
|
|
|
|
terminal.addProperty("App::PropertyString", "QetTerminalLocalRoutePointsJson", "QET Routing", "")
|
|
|
|
|
|
|
|
terminal.QetTerminalLocalRoutePointsJson = json.dumps([[0, 0, 0], [10, 0, 0], [10, 30, 0]])
|
|
|
|
|
|
|
|
routing_network.create_route_carrier(
|
|
|
|
|
|
|
|
doc,
|
|
|
|
|
|
|
|
[app.Vector(10, 80, 0), app.Vector(110, 80, 0)],
|
|
|
|
|
|
|
|
project_uuid="project-1",
|
|
|
|
|
|
|
|
kind="UserPath",
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
created = routing_network.create_terminal_access_carriers_from_document(
|
|
|
|
|
|
|
|
doc,
|
|
|
|
|
|
|
|
project_uuid="project-1",
|
|
|
|
|
|
|
|
terminal_exit_length=20.0,
|
|
|
|
|
|
|
|
max_distance=100.0,
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.assertEqual(1, len(created))
|
|
|
|
|
|
|
|
self.assertEqual(
|
|
|
|
|
|
|
|
[(0.0, 0.0, 0.0), (10.0, 0.0, 0.0), (10.0, 30.0, 0.0)],
|
|
|
|
|
|
|
|
[(p.x, p.y, p.z) for p in created[0].Points[:3]],
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_generate_routing_paths_refreshes_selected_user_path_without_duplicate(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", "UserRouteSketch")
|
|
|
|
|
|
|
|
route_path.Shape = FakeShape(
|
|
|
|
|
|
|
|
FakeBoundBox(0, 100, 0, 80, 20, 20),
|
|
|
|
|
|
|
|
edges=[FakeEdge(app.Vector(0, 0, 20), app.Vector(100, 0, 20))],
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
gui.Selection = types.SimpleNamespace(
|
|
|
|
|
|
|
|
getSelection=lambda: [],
|
|
|
|
|
|
|
|
getSelectionEx=lambda: [FakeSelectionItem(obj=route_path)],
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
first = auto_routing_panel.AutoRoutingController().generate_routing_paths()
|
|
|
|
|
|
|
|
route_path.Shape = FakeShape(
|
|
|
|
|
|
|
|
FakeBoundBox(0, 200, 0, 80, 20, 20),
|
|
|
|
|
|
|
|
edges=[FakeEdge(app.Vector(0, 0, 20), app.Vector(200, 0, 20))],
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
second = auto_routing_panel.AutoRoutingController().generate_routing_paths()
|
|
|
|
|
|
|
|
user_paths = [
|
|
|
|
|
|
|
|
item
|
|
|
|
|
|
|
|
for item in routing_network.collect_route_carriers(doc)
|
|
|
|
|
|
|
|
if item.QetRouteCarrierKind == "UserPath"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.assertEqual(1, first["user_path_carriers"])
|
|
|
|
|
|
|
|
self.assertEqual(0, second["user_path_carriers"])
|
|
|
|
|
|
|
|
self.assertEqual(1, len(user_paths))
|
|
|
|
|
|
|
|
self.assertEqual([(0.0, 0.0, 20.0), (200.0, 0.0, 20.0)], [(p.x, p.y, p.z) for p in user_paths[0].Points])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_eplan_connection_route_can_use_generated_user_path(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")
|
|
|
|
|
|
|
|
start = _terminal(doc, terminal_objects, "TerminalStart", "terminal-start", app.Vector(0, 0, 0))
|
|
|
|
|
|
|
|
end = _terminal(doc, terminal_objects, "TerminalEnd", "terminal-end", app.Vector(200, 0, 0))
|
|
|
|
|
|
|
|
routing_network.create_route_carrier(
|
|
|
|
|
|
|
|
doc,
|
|
|
|
|
|
|
|
[app.Vector(0, 0, 20), app.Vector(200, 0, 20)],
|
|
|
|
|
|
|
|
project_uuid="project-1",
|
|
|
|
|
|
|
|
kind="UserPath",
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
result = auto_routing.route_eplan_connection_between_terminals(doc, start, end)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.assertEqual("Routed", result["route_status"])
|
|
|
|
|
|
|
|
self.assertIn("UserPath", result["route_track"]["carrier_kinds"])
|
|
|
|
|
|
|
|
|
|
|
|
def test_generate_routing_paths_does_not_duplicate_selected_wire_duct_carriers(self):
|
|
|
|
def test_generate_routing_paths_does_not_duplicate_selected_wire_duct_carriers(self):
|
|
|
|
_install_fake_freecad()
|
|
|
|
_install_fake_freecad()
|
|
|
|
terminal_objects, _wiring_objects, routing_network, _auto_routing = _reload_modules()
|
|
|
|
terminal_objects, _wiring_objects, routing_network, _auto_routing = _reload_modules()
|
|
|
|
@ -1814,6 +2041,39 @@ class AutoRoutingTest(unittest.TestCase):
|
|
|
|
self.assertEqual("z", report["routes"][1]["lane"]["axis"])
|
|
|
|
self.assertEqual("z", report["routes"][1]["lane"]["axis"])
|
|
|
|
self.assertEqual(8.0, report["routes"][1]["lane"]["offset_mm"])
|
|
|
|
self.assertEqual(8.0, report["routes"][1]["lane"]["offset_mm"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_auto_routing_panel_command_button_style_keeps_text_visible(self):
|
|
|
|
|
|
|
|
_install_fake_freecad()
|
|
|
|
|
|
|
|
_terminal_objects, _wiring_objects, _routing_network, _auto_routing = _reload_modules()
|
|
|
|
|
|
|
|
auto_routing_panel = importlib.import_module("AutoRoutingPanel")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FakeButton:
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
|
|
|
|
self.text = ""
|
|
|
|
|
|
|
|
self.tooltip = ""
|
|
|
|
|
|
|
|
self.minimum_height = 0
|
|
|
|
|
|
|
|
self.stylesheet = ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def setText(self, text):
|
|
|
|
|
|
|
|
self.text = text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def setToolTip(self, tooltip):
|
|
|
|
|
|
|
|
self.tooltip = tooltip
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def setMinimumHeight(self, height):
|
|
|
|
|
|
|
|
self.minimum_height = height
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def setStyleSheet(self, stylesheet):
|
|
|
|
|
|
|
|
self.stylesheet = stylesheet
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
button = FakeButton()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto_routing_panel._style_command_button(button, "生成布线连接", "按导线任务布线")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.assertEqual("生成布线连接", button.text)
|
|
|
|
|
|
|
|
self.assertEqual("按导线任务布线", button.tooltip)
|
|
|
|
|
|
|
|
self.assertGreaterEqual(button.minimum_height, 28)
|
|
|
|
|
|
|
|
self.assertIn("color", button.stylesheet)
|
|
|
|
|
|
|
|
|
|
|
|
def test_eplan_connection_route_rejects_far_network_entry_to_avoid_huge_render_bbox(self):
|
|
|
|
def test_eplan_connection_route_rejects_far_network_entry_to_avoid_huge_render_bbox(self):
|
|
|
|
_install_fake_freecad()
|
|
|
|
_install_fake_freecad()
|
|
|
|
terminal_objects, _wiring_objects, routing_network, auto_routing = _reload_modules()
|
|
|
|
terminal_objects, _wiring_objects, routing_network, auto_routing = _reload_modules()
|
|
|
|
@ -2208,6 +2468,151 @@ class AutoRoutingTest(unittest.TestCase):
|
|
|
|
self.assertTrue(report["missing_endpoint_samples"][0]["start_found"])
|
|
|
|
self.assertTrue(report["missing_endpoint_samples"][0]["start_found"])
|
|
|
|
self.assertFalse(report["missing_endpoint_samples"][0]["end_found"])
|
|
|
|
self.assertFalse(report["missing_endpoint_samples"][0]["end_found"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_route_eplan_connections_from_payload_skips_resolved_tasks_without_route_network(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))
|
|
|
|
|
|
|
|
payload = {
|
|
|
|
|
|
|
|
"project_uuid": "project-1",
|
|
|
|
|
|
|
|
"wires": [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"wire_id": "wire-{0}".format(index),
|
|
|
|
|
|
|
|
"start_terminal_uuid": "terminal-start",
|
|
|
|
|
|
|
|
"end_terminal_uuid": "terminal-end",
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
for index in range(3)
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
original_route = auto_routing.route_eplan_connection_between_terminals
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def fail_if_called(*_args, **_kwargs):
|
|
|
|
|
|
|
|
raise AssertionError("batch route must not call per-wire routing without route carriers")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto_routing.route_eplan_connection_between_terminals = fail_if_called
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
report = auto_routing.route_eplan_connections_from_payload(doc, payload)
|
|
|
|
|
|
|
|
finally:
|
|
|
|
|
|
|
|
auto_routing.route_eplan_connection_between_terminals = original_route
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.assertEqual(0, report["routed"])
|
|
|
|
|
|
|
|
self.assertEqual(3, report["skipped_missing_route_network"])
|
|
|
|
|
|
|
|
self.assertEqual(3, report["route_status_counts"]["MissingRouteNetwork"])
|
|
|
|
|
|
|
|
self.assertEqual([], report["errors"])
|
|
|
|
|
|
|
|
self.assertEqual([], wiring_objects.iter_routed_wire_objects(doc))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_route_eplan_connection_tasks_marks_task_missing_route_network_when_skipped(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))
|
|
|
|
|
|
|
|
task = wiring_objects.create_wire_task(
|
|
|
|
|
|
|
|
doc,
|
|
|
|
|
|
|
|
"project-1",
|
|
|
|
|
|
|
|
"wire-missing-network",
|
|
|
|
|
|
|
|
"N1",
|
|
|
|
|
|
|
|
"terminal-start",
|
|
|
|
|
|
|
|
"terminal-end",
|
|
|
|
|
|
|
|
"instance-a",
|
|
|
|
|
|
|
|
"instance-b",
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
task.RouteStatus = "Routed"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
report = auto_routing.route_eplan_connection_tasks(doc)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.assertEqual(0, report["routed"])
|
|
|
|
|
|
|
|
self.assertEqual(1, report["skipped_missing_route_network"])
|
|
|
|
|
|
|
|
self.assertEqual("MissingRouteNetwork", task.RouteStatus)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_eplan_connection_route_prefers_wire_duct_over_shorter_routing_range(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")
|
|
|
|
|
|
|
|
start = _terminal(doc, terminal_objects, "TerminalStart", "terminal-start", app.Vector(0, 0, 0))
|
|
|
|
|
|
|
|
end = _terminal(doc, terminal_objects, "TerminalEnd", "terminal-end", app.Vector(300, 0, 0))
|
|
|
|
|
|
|
|
routing_network.create_route_carrier(
|
|
|
|
|
|
|
|
doc,
|
|
|
|
|
|
|
|
[app.Vector(0, 0, 20), app.Vector(300, 0, 20)],
|
|
|
|
|
|
|
|
project_uuid="project-1",
|
|
|
|
|
|
|
|
kind="RoutingRange",
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
routing_network.create_route_carrier(
|
|
|
|
|
|
|
|
doc,
|
|
|
|
|
|
|
|
[
|
|
|
|
|
|
|
|
app.Vector(0, 0, 20),
|
|
|
|
|
|
|
|
app.Vector(0, 1200, 20),
|
|
|
|
|
|
|
|
app.Vector(300, 1200, 20),
|
|
|
|
|
|
|
|
app.Vector(300, 0, 20),
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
project_uuid="project-1",
|
|
|
|
|
|
|
|
kind="WireDuct",
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
result = auto_routing.route_eplan_connection_between_terminals(doc, start, end)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.assertIn("WireDuct", result["route_track"]["carrier_kinds"])
|
|
|
|
|
|
|
|
self.assertNotIn("RoutingRange", result["route_track"]["carrier_kinds"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_route_eplan_connections_from_payload_skips_tasks_when_carriers_have_no_segments(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))
|
|
|
|
|
|
|
|
broken_carrier = doc.addObject("Part::Feature", "BrokenCarrier")
|
|
|
|
|
|
|
|
terminal_objects.ensure_string_property(
|
|
|
|
|
|
|
|
broken_carrier,
|
|
|
|
|
|
|
|
"QetRoutingRole",
|
|
|
|
|
|
|
|
"QET Routing",
|
|
|
|
|
|
|
|
"Routing role marker",
|
|
|
|
|
|
|
|
"RoutingCarrier",
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
terminal_objects.ensure_string_property(
|
|
|
|
|
|
|
|
broken_carrier,
|
|
|
|
|
|
|
|
"QetRouteCarrierKind",
|
|
|
|
|
|
|
|
"QET Routing",
|
|
|
|
|
|
|
|
"Route carrier kind",
|
|
|
|
|
|
|
|
"WireDuct",
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
terminal_objects.ensure_bool_property(
|
|
|
|
|
|
|
|
broken_carrier,
|
|
|
|
|
|
|
|
"CanRouteWire",
|
|
|
|
|
|
|
|
"QET Routing",
|
|
|
|
|
|
|
|
"Whether routing connections can use this path",
|
|
|
|
|
|
|
|
True,
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
payload = {
|
|
|
|
|
|
|
|
"project_uuid": "project-1",
|
|
|
|
|
|
|
|
"wires": [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"wire_id": "wire-a",
|
|
|
|
|
|
|
|
"start_terminal_uuid": "terminal-start",
|
|
|
|
|
|
|
|
"end_terminal_uuid": "terminal-end",
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
report = auto_routing.route_eplan_connections_from_payload(doc, payload)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.assertEqual(1, report["route_network_carriers"])
|
|
|
|
|
|
|
|
self.assertEqual(0, report["route_network_segments"])
|
|
|
|
|
|
|
|
self.assertEqual(0, report["route_network_nodes"])
|
|
|
|
|
|
|
|
self.assertEqual(0, report["routed"])
|
|
|
|
|
|
|
|
self.assertEqual(1, report["skipped_missing_route_network"])
|
|
|
|
|
|
|
|
self.assertEqual(1, report["route_status_counts"]["MissingRouteNetwork"])
|
|
|
|
|
|
|
|
self.assertEqual([], report["errors"])
|
|
|
|
|
|
|
|
self.assertEqual([], wiring_objects.iter_routed_wire_objects(doc))
|
|
|
|
|
|
|
|
|
|
|
|
def test_route_eplan_connections_writes_diagnostic_object_for_missing_terminal(self):
|
|
|
|
def test_route_eplan_connections_writes_diagnostic_object_for_missing_terminal(self):
|
|
|
|
_install_fake_freecad()
|
|
|
|
_install_fake_freecad()
|
|
|
|
terminal_objects, _wiring_objects, _routing_network, auto_routing = _reload_modules()
|
|
|
|
terminal_objects, _wiring_objects, _routing_network, auto_routing = _reload_modules()
|
|
|
|
@ -2236,6 +2641,57 @@ class AutoRoutingTest(unittest.TestCase):
|
|
|
|
self.assertEqual("RoutingConnectionBatch", diagnostic.QetDiagnosticKind)
|
|
|
|
self.assertEqual("RoutingConnectionBatch", diagnostic.QetDiagnosticKind)
|
|
|
|
self.assertIn("terminal-missing", diagnostic.QetDiagnosticJson)
|
|
|
|
self.assertIn("terminal-missing", diagnostic.QetDiagnosticJson)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_route_eplan_connections_writes_compact_batch_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, "TerminalStartA", "terminal-start-a", app.Vector(0, 0, 0))
|
|
|
|
|
|
|
|
_terminal(doc, terminal_objects, "TerminalEndA", "terminal-end-a", app.Vector(100, 0, 0))
|
|
|
|
|
|
|
|
_terminal(doc, terminal_objects, "TerminalStartB", "terminal-start-b", app.Vector(0, 20, 0))
|
|
|
|
|
|
|
|
_terminal(doc, terminal_objects, "TerminalEndB", "terminal-end-b", app.Vector(100, 20, 0))
|
|
|
|
|
|
|
|
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_route_carrier(
|
|
|
|
|
|
|
|
doc,
|
|
|
|
|
|
|
|
[app.Vector(0, 20, 20), app.Vector(100, 20, 20)],
|
|
|
|
|
|
|
|
project_uuid="project-1",
|
|
|
|
|
|
|
|
kind="WireDuct",
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
payload = {
|
|
|
|
|
|
|
|
"project_uuid": "project-1",
|
|
|
|
|
|
|
|
"wires": [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"wire_id": "wire-a",
|
|
|
|
|
|
|
|
"wire_label": "N1",
|
|
|
|
|
|
|
|
"start_terminal_uuid": "terminal-start-a",
|
|
|
|
|
|
|
|
"end_terminal_uuid": "terminal-end-a",
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"wire_id": "wire-b",
|
|
|
|
|
|
|
|
"wire_label": "N2",
|
|
|
|
|
|
|
|
"start_terminal_uuid": "terminal-start-b",
|
|
|
|
|
|
|
|
"end_terminal_uuid": "terminal-end-b",
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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(2, len(report["routes"]))
|
|
|
|
|
|
|
|
self.assertNotIn("routes", diagnostic_payload)
|
|
|
|
|
|
|
|
self.assertEqual(2, diagnostic_payload["route_sample_count"])
|
|
|
|
|
|
|
|
self.assertEqual(2, len(diagnostic_payload["route_samples"]))
|
|
|
|
|
|
|
|
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_reports_total_connection_route_length(self):
|
|
|
|
def test_route_eplan_connections_reports_total_connection_route_length(self):
|
|
|
|
_install_fake_freecad()
|
|
|
|
_install_fake_freecad()
|
|
|
|
terminal_objects, _wiring_objects, routing_network, auto_routing = _reload_modules()
|
|
|
|
terminal_objects, _wiring_objects, routing_network, auto_routing = _reload_modules()
|
|
|
|
@ -2268,6 +2724,164 @@ class AutoRoutingTest(unittest.TestCase):
|
|
|
|
self.assertEqual(report["total_length_mm"], report["routes"][0]["length_mm"])
|
|
|
|
self.assertEqual(report["total_length_mm"], report["routes"][0]["length_mm"])
|
|
|
|
self.assertIn("总长度", message)
|
|
|
|
self.assertIn("总长度", message)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_route_eplan_connections_hides_route_carriers_after_routing_by_default(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))
|
|
|
|
|
|
|
|
carrier = routing_network.create_route_carrier(
|
|
|
|
|
|
|
|
doc,
|
|
|
|
|
|
|
|
[app.Vector(0, 0, 20), app.Vector(100, 0, 20)],
|
|
|
|
|
|
|
|
project_uuid="project-1",
|
|
|
|
|
|
|
|
kind="WireDuct",
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
payload = {
|
|
|
|
|
|
|
|
"project_uuid": "project-1",
|
|
|
|
|
|
|
|
"wires": [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"wire_id": "wire-1",
|
|
|
|
|
|
|
|
"start_terminal_uuid": "terminal-start",
|
|
|
|
|
|
|
|
"end_terminal_uuid": "terminal-end",
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
report = auto_routing.route_eplan_connections(
|
|
|
|
|
|
|
|
doc,
|
|
|
|
|
|
|
|
payload=payload,
|
|
|
|
|
|
|
|
update_network=False,
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.assertEqual(1, report["routed"])
|
|
|
|
|
|
|
|
self.assertEqual(1, report["hidden_route_carriers"])
|
|
|
|
|
|
|
|
self.assertFalse(carrier.ViewObject.Visibility)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_route_eplan_connections_batch_recomputes_once_after_created_wires(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, "TerminalStartA", "terminal-start-a", app.Vector(0, 0, 0))
|
|
|
|
|
|
|
|
_terminal(doc, terminal_objects, "TerminalEndA", "terminal-end-a", app.Vector(100, 0, 0))
|
|
|
|
|
|
|
|
_terminal(doc, terminal_objects, "TerminalStartB", "terminal-start-b", app.Vector(0, 10, 0))
|
|
|
|
|
|
|
|
_terminal(doc, terminal_objects, "TerminalEndB", "terminal-end-b", app.Vector(100, 10, 0))
|
|
|
|
|
|
|
|
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_route_carrier(
|
|
|
|
|
|
|
|
doc,
|
|
|
|
|
|
|
|
[app.Vector(0, 10, 20), app.Vector(100, 10, 20)],
|
|
|
|
|
|
|
|
project_uuid="project-1",
|
|
|
|
|
|
|
|
kind="WireDuct",
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
recompute_count = {"value": 0}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def count_recompute():
|
|
|
|
|
|
|
|
recompute_count["value"] += 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
doc.recompute = count_recompute
|
|
|
|
|
|
|
|
payload = {
|
|
|
|
|
|
|
|
"project_uuid": "project-1",
|
|
|
|
|
|
|
|
"wires": [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"wire_id": "wire-a",
|
|
|
|
|
|
|
|
"start_terminal_uuid": "terminal-start-a",
|
|
|
|
|
|
|
|
"end_terminal_uuid": "terminal-end-a",
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"wire_id": "wire-b",
|
|
|
|
|
|
|
|
"start_terminal_uuid": "terminal-start-b",
|
|
|
|
|
|
|
|
"end_terminal_uuid": "terminal-end-b",
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
report = auto_routing.route_eplan_connections_from_payload(doc, payload)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.assertEqual(2, report["routed"])
|
|
|
|
|
|
|
|
self.assertEqual(1, recompute_count["value"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_route_eplan_connections_replaces_existing_routed_wires_for_same_batch(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="WireDuct",
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
payload = {
|
|
|
|
|
|
|
|
"project_uuid": "project-1",
|
|
|
|
|
|
|
|
"wires": [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"wire_id": "wire-repeat",
|
|
|
|
|
|
|
|
"start_terminal_uuid": "terminal-start",
|
|
|
|
|
|
|
|
"end_terminal_uuid": "terminal-end",
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
first = auto_routing.route_eplan_connections_from_payload(doc, payload)
|
|
|
|
|
|
|
|
second = auto_routing.route_eplan_connections_from_payload(doc, payload)
|
|
|
|
|
|
|
|
routed_wires = list(wiring_objects.iter_routed_wire_objects(doc))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.assertEqual(1, first["routed"])
|
|
|
|
|
|
|
|
self.assertEqual(1, second["routed"])
|
|
|
|
|
|
|
|
self.assertEqual(1, second["replaced_routed_connections"])
|
|
|
|
|
|
|
|
self.assertEqual(1, len(routed_wires))
|
|
|
|
|
|
|
|
self.assertEqual("wire-repeat", routed_wires[0].QetWireUuid)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_clear_routing_connections_resets_task_status_and_batch_diagnostics(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="WireDuct",
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
task = wiring_objects.create_wire_task(
|
|
|
|
|
|
|
|
doc,
|
|
|
|
|
|
|
|
"project-1",
|
|
|
|
|
|
|
|
"wire-clear",
|
|
|
|
|
|
|
|
"N1",
|
|
|
|
|
|
|
|
"terminal-start",
|
|
|
|
|
|
|
|
"terminal-end",
|
|
|
|
|
|
|
|
"instance-a",
|
|
|
|
|
|
|
|
"instance-b",
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
report = auto_routing.route_eplan_connection_tasks(doc)
|
|
|
|
|
|
|
|
diagnostic_group = doc.getObject("QETWiring_05_Diagnostics")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.assertEqual(1, report["routed"])
|
|
|
|
|
|
|
|
self.assertEqual("Routed", task.RouteStatus)
|
|
|
|
|
|
|
|
self.assertEqual(1, len(list(getattr(diagnostic_group, "Group", []) or [])))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
removed = auto_routing.clear_routing_connections(doc)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.assertEqual(1, removed)
|
|
|
|
|
|
|
|
self.assertEqual("Task", task.RouteStatus)
|
|
|
|
|
|
|
|
self.assertEqual([], wiring_objects.iter_routed_wire_objects(doc))
|
|
|
|
|
|
|
|
self.assertEqual([], list(getattr(diagnostic_group, "Group", []) or []))
|
|
|
|
|
|
|
|
|
|
|
|
def test_route_report_includes_route_source_sample_when_available(self):
|
|
|
|
def test_route_report_includes_route_source_sample_when_available(self):
|
|
|
|
_install_fake_freecad()
|
|
|
|
_install_fake_freecad()
|
|
|
|
_terminal_objects, _wiring_objects, _routing_network, auto_routing = _reload_modules()
|
|
|
|
_terminal_objects, _wiring_objects, _routing_network, auto_routing = _reload_modules()
|
|
|
|
@ -2332,6 +2946,69 @@ class AutoRoutingTest(unittest.TestCase):
|
|
|
|
|
|
|
|
|
|
|
|
self.assertIn("并行错位:最大 lane 2,间距 10.0 mm。", message)
|
|
|
|
self.assertIn("并行错位:最大 lane 2,间距 10.0 mm。", message)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_route_report_includes_replaced_routed_connection_count(self):
|
|
|
|
|
|
|
|
_install_fake_freecad()
|
|
|
|
|
|
|
|
_terminal_objects, _wiring_objects, _routing_network, auto_routing = _reload_modules()
|
|
|
|
|
|
|
|
report = {
|
|
|
|
|
|
|
|
"routed": 1,
|
|
|
|
|
|
|
|
"collision_warnings": 0,
|
|
|
|
|
|
|
|
"skipped_missing_terminal": 0,
|
|
|
|
|
|
|
|
"replaced_routed_connections": 2,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
message = auto_routing.format_eplan_connection_route_report(report)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.assertIn("已替换旧布线连接:2 条。", message)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_route_report_includes_hidden_route_carrier_count(self):
|
|
|
|
|
|
|
|
_install_fake_freecad()
|
|
|
|
|
|
|
|
_terminal_objects, _wiring_objects, _routing_network, auto_routing = _reload_modules()
|
|
|
|
|
|
|
|
report = {
|
|
|
|
|
|
|
|
"routed": 1,
|
|
|
|
|
|
|
|
"collision_warnings": 0,
|
|
|
|
|
|
|
|
"skipped_missing_terminal": 0,
|
|
|
|
|
|
|
|
"hidden_route_carriers": 3,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
message = auto_routing.format_eplan_connection_route_report(report)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.assertIn("已隐藏走线路径辅助对象:3 条。", message)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_route_report_warns_when_routes_use_surface_or_auxiliary_paths(self):
|
|
|
|
|
|
|
|
_install_fake_freecad()
|
|
|
|
|
|
|
|
_terminal_objects, _wiring_objects, _routing_network, auto_routing = _reload_modules()
|
|
|
|
|
|
|
|
report = {
|
|
|
|
|
|
|
|
"routed": 2,
|
|
|
|
|
|
|
|
"collision_warnings": 0,
|
|
|
|
|
|
|
|
"skipped_missing_terminal": 0,
|
|
|
|
|
|
|
|
"routes": [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"wire_label": "N1",
|
|
|
|
|
|
|
|
"route_track": {
|
|
|
|
|
|
|
|
"carrier_kinds": {
|
|
|
|
|
|
|
|
"TerminalAccess": 2,
|
|
|
|
|
|
|
|
"WireDuct": 1,
|
|
|
|
|
|
|
|
"RoutingRange": 2,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"wire_label": "N2",
|
|
|
|
|
|
|
|
"route_track": {
|
|
|
|
|
|
|
|
"carrier_kinds": {
|
|
|
|
|
|
|
|
"TerminalAccess": 2,
|
|
|
|
|
|
|
|
"WireDuct": 3,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
message = auto_routing.format_eplan_connection_route_report(report)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.assertIn("路径质量提示:1 条导线使用布线面/辅助路径", message)
|
|
|
|
|
|
|
|
self.assertIn("示例 N1 使用布线面。", message)
|
|
|
|
|
|
|
|
|
|
|
|
def test_route_report_warns_when_parallel_lanes_exceed_track_capacity(self):
|
|
|
|
def test_route_report_warns_when_parallel_lanes_exceed_track_capacity(self):
|
|
|
|
_install_fake_freecad()
|
|
|
|
_install_fake_freecad()
|
|
|
|
_terminal_objects, _wiring_objects, _routing_network, auto_routing = _reload_modules()
|
|
|
|
_terminal_objects, _wiring_objects, _routing_network, auto_routing = _reload_modules()
|
|
|
|
@ -2737,6 +3414,7 @@ class AutoRoutingTest(unittest.TestCase):
|
|
|
|
self.assertEqual(0, report["routes"][0]["lane"]["index"])
|
|
|
|
self.assertEqual(0, report["routes"][0]["lane"]["index"])
|
|
|
|
self.assertEqual(1, report["routes"][1]["lane"]["index"])
|
|
|
|
self.assertEqual(1, report["routes"][1]["lane"]["index"])
|
|
|
|
routed_group = doc.getObject("QETWiring_04_Routed")
|
|
|
|
routed_group = doc.getObject("QETWiring_04_Routed")
|
|
|
|
|
|
|
|
self.assertEqual(2, len(list(getattr(routed_group, "Group", []) or [])))
|
|
|
|
second_wire = [
|
|
|
|
second_wire = [
|
|
|
|
wire
|
|
|
|
wire
|
|
|
|
for wire in list(getattr(routed_group, "Group", []) or [])
|
|
|
|
for wire in list(getattr(routed_group, "Group", []) or [])
|
|
|
|
@ -3101,6 +3779,25 @@ class AutoRoutingTest(unittest.TestCase):
|
|
|
|
self.assertIn("首个错误:没有可用的线槽/路由路径网络", message)
|
|
|
|
self.assertIn("首个错误:没有可用的线槽/路由路径网络", message)
|
|
|
|
self.assertIn("缺失示例:terminal-a -> terminal-b", message)
|
|
|
|
self.assertIn("缺失示例:terminal-a -> terminal-b", message)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_route_eplan_connections_report_calls_out_missing_route_network(self):
|
|
|
|
|
|
|
|
_install_fake_freecad()
|
|
|
|
|
|
|
|
_terminal_objects, _wiring_objects, _routing_network, auto_routing = _reload_modules()
|
|
|
|
|
|
|
|
report = {
|
|
|
|
|
|
|
|
"total_wires": 3,
|
|
|
|
|
|
|
|
"routed": 0,
|
|
|
|
|
|
|
|
"collision_warnings": 0,
|
|
|
|
|
|
|
|
"skipped_missing_terminal": 0,
|
|
|
|
|
|
|
|
"skipped_missing_route_network": 3,
|
|
|
|
|
|
|
|
"route_status_counts": {
|
|
|
|
|
|
|
|
"MissingRouteNetwork": 3,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
message = auto_routing.format_eplan_connection_route_report(report)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.assertIn("缺少布线路径网络 3 条", message)
|
|
|
|
|
|
|
|
self.assertIn("请先生成线槽、布线面或布线路径网络", message)
|
|
|
|
|
|
|
|
|
|
|
|
def test_route_eplan_connections_report_includes_readable_missing_endpoint_labels(self):
|
|
|
|
def test_route_eplan_connections_report_includes_readable_missing_endpoint_labels(self):
|
|
|
|
_install_fake_freecad()
|
|
|
|
_install_fake_freecad()
|
|
|
|
_terminal_objects, _wiring_objects, _routing_network, auto_routing = _reload_modules()
|
|
|
|
_terminal_objects, _wiring_objects, _routing_network, auto_routing = _reload_modules()
|
|
|
|
@ -3249,6 +3946,8 @@ class AutoRoutingTest(unittest.TestCase):
|
|
|
|
self.assertEqual(0, report["local_terminals"])
|
|
|
|
self.assertEqual(0, report["local_terminals"])
|
|
|
|
self.assertEqual([], wiring_objects.iter_routed_wire_objects(doc))
|
|
|
|
self.assertEqual([], wiring_objects.iter_routed_wire_objects(doc))
|
|
|
|
self.assertEqual("qet", indexed["qet-terminal-p1"].QetTerminalBindingMode)
|
|
|
|
self.assertEqual("qet", indexed["qet-terminal-p1"].QetTerminalBindingMode)
|
|
|
|
|
|
|
|
self.assertFalse(indexed["qet-terminal-p1"].ViewObject.Visibility)
|
|
|
|
|
|
|
|
self.assertFalse(indexed["qet-terminal-p2"].ViewObject.Visibility)
|
|
|
|
|
|
|
|
|
|
|
|
def test_route_eplan_connections_rebinds_local_template_terminals_from_wire_endpoints(self):
|
|
|
|
def test_route_eplan_connections_rebinds_local_template_terminals_from_wire_endpoints(self):
|
|
|
|
_install_fake_freecad()
|
|
|
|
_install_fake_freecad()
|
|
|
|
@ -3324,6 +4023,8 @@ class AutoRoutingTest(unittest.TestCase):
|
|
|
|
self.assertIn("qet-terminal-p1", indexed)
|
|
|
|
self.assertIn("qet-terminal-p1", indexed)
|
|
|
|
self.assertIn("qet-terminal-p2", indexed)
|
|
|
|
self.assertIn("qet-terminal-p2", indexed)
|
|
|
|
self.assertEqual("qet", indexed["qet-terminal-p1"].QetTerminalBindingMode)
|
|
|
|
self.assertEqual("qet", indexed["qet-terminal-p1"].QetTerminalBindingMode)
|
|
|
|
|
|
|
|
self.assertFalse(indexed["qet-terminal-p1"].ViewObject.Visibility)
|
|
|
|
|
|
|
|
self.assertFalse(indexed["qet-terminal-p2"].ViewObject.Visibility)
|
|
|
|
|
|
|
|
|
|
|
|
def test_clear_route_carriers_keeps_routed_wires(self):
|
|
|
|
def test_clear_route_carriers_keeps_routed_wires(self):
|
|
|
|
_install_fake_freecad()
|
|
|
|
_install_fake_freecad()
|
|
|
|
|