feat: 扩展过线孔布线桥接

dev
Zhaowenlong 3 weeks ago
parent 4dd33c0365
commit 8388f9d15c

@ -334,6 +334,8 @@ src/Mod/FreeCADExchange/InitGui.py
生成线槽 carrier 时,系统除了 `WireDuct` 中心路径,还会在线槽两端生成 `WireDuctOpenEnd` 横向路径;对象名或标签包含 `Wiring Cut-Out`、`wire cutout`、`穿线孔`、`过线孔` 等语义时,会生成 `WiringCutOut` 穿线路径载体。
`WiringCutOut` 不是按开孔实体外轮廓布线,而是按开孔包围盒最薄方向生成一条虚拟穿线路径,并在穿孔方向两端做小距离外扩。这样安装板、隔板或线槽侧壁上的孔可以接到孔两侧附近的线槽中心线或支撑面网格,避免路径只停留在板厚范围内而无法连通网络。
自动生成的 carrier 会随源对象生命周期刷新:源对象仍有效时更新几何;安装板尺寸变化时同步增删 `RoutingRange` 网格线;源对象被删除或不再满足线槽/支撑面规则时,下一次生成布线路径网络会删除对应自动 carrier并撤销该源对象的穿越/支撑面障碍模式。用户手工创建、没有源对象元数据的 carrier 不会被这一步自动删除。
### 5.3 布线连接功能
@ -408,6 +410,7 @@ tests/python/freecad_exchange_auto_routing_test.py
22. 线槽端部会生成 `WireDuctOpenEnd` 横向路径,穿线孔/过线孔会生成 `WiringCutOut` carrier。
23. 导线会保存 routing track网络检查会生成 `RoutingPathNetwork` 诊断对象。
24. 自动生成的线槽、过线孔和支撑面 carrier 会在源对象移动、缩放、删除或失效后刷新/清理。
25. `WiringCutOut` 会在穿孔方向外扩虚拟路径,用于桥接开孔两侧附近的线槽或支撑面网络。
已完成 FreeCAD smoke

@ -38,6 +38,7 @@ DEFAULT_ROUTE_PATH_FACE_OFFSET = 2.0
DEFAULT_AUTO_WIRE_DUCT_MIN_ASPECT = 2.5
DEFAULT_TERMINAL_ACCESS_MAX_DISTANCE = 1000.0
DEFAULT_ADJOINING_DUCT_TOLERANCE = 5.0
DEFAULT_WIRING_CUT_OUT_BRIDGE_EXTENSION = 20.0
WIRE_DUCT_OBSTACLE_MODE = "PassThrough"
SUPPORT_SURFACE_OBSTACLE_MODE = "SupportSurface"
WIRE_DUCT_NAME_KEYWORDS = (
@ -1466,7 +1467,7 @@ def _sync_wire_duct_source_carriers(doc, source, spec, project_uuid="", capacity
return True
def _wiring_cut_out_points_from_bbox(bbox):
def _wiring_cut_out_points_from_bbox(bbox, bridge_extension=0.0):
extents = _bbox_extents(bbox)
if not extents:
return []
@ -1482,6 +1483,9 @@ def _wiring_cut_out_points_from_bbox(bbox):
fallback = max(other_extents or [DEFAULT_WIRE_DUCT_OPEN_END_MIN_LENGTH])
low = _axis_value(center, through_axis) - fallback * 0.5
high = _axis_value(center, through_axis) + fallback * 0.5
extension = max(float(bridge_extension or 0.0), 0.0)
low -= extension
high += extension
start = _set_axis(center, through_axis, low)
end = _set_axis(center, through_axis, high)
if _distance(start, end) <= DEFAULT_NODE_TOLERANCE:
@ -1887,7 +1891,11 @@ def create_wire_duct_carriers_from_document(
return created
def create_wiring_cut_out_carriers_from_document(doc, project_uuid=""):
def create_wiring_cut_out_carriers_from_document(
doc,
project_uuid="",
bridge_extension=DEFAULT_WIRING_CUT_OUT_BRIDGE_EXTENSION,
):
"""Create pass-through route carriers for wiring cut-out objects."""
cleanup_invalid_source_carriers(doc)
created = []
@ -1895,7 +1903,7 @@ def create_wiring_cut_out_carriers_from_document(doc, project_uuid=""):
bbox = _bound_box_from_object(source)
if bbox is None:
continue
points = _wiring_cut_out_points_from_bbox(bbox)
points = _wiring_cut_out_points_from_bbox(bbox, bridge_extension=bridge_extension)
if len(points) < 2:
continue
live_carrier = _live_source_carrier(doc, source)

@ -1295,7 +1295,40 @@ class AutoRoutingTest(unittest.TestCase):
self.assertEqual(1, first["wiring_cut_out_carriers"])
self.assertEqual(0, second["wiring_cut_out_carriers"])
self.assertEqual(1, len(cut_out_carriers))
self.assertEqual([(70.0, -2.0, 20.0), (70.0, 2.0, 20.0)], [(p.x, p.y, p.z) for p in cut_out_carriers[0].Points])
self.assertEqual([(70.0, -22.0, 20.0), (70.0, 22.0, 20.0)], [(p.x, p.y, p.z) for p in cut_out_carriers[0].Points])
def test_wiring_cut_out_bridges_nearby_ducts_on_both_sides_of_panel(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"]
doc = FakeDocument()
app.ActiveDocument = doc
terminal_objects.ensure_root_group(doc, "project-1")
start = _terminal(doc, terminal_objects, "TerminalStart", "terminal-start", app.Vector(0, -20, 0))
end = _terminal(doc, terminal_objects, "TerminalEnd", "terminal-end", app.Vector(100, 20, 0))
routing_network.create_route_carrier(
doc,
[app.Vector(0, -20, 20), app.Vector(50, -20, 20)],
project_uuid="project-1",
kind="WireDuct",
)
routing_network.create_route_carrier(
doc,
[app.Vector(50, 20, 20), app.Vector(100, 20, 20)],
project_uuid="project-1",
kind="WireDuct",
)
cut_out = doc.addObject("Part::Feature", "WiringCutoutA")
cut_out.Label = "过线孔A"
cut_out.Shape = FakeShape(FakeBoundBox(45, 55, -2, 2, 15, 25))
auto_routing_panel.AutoRoutingController().generate_routing_paths()
result = auto_routing.route_eplan_connection_between_terminals(doc, start, end)
self.assertEqual("Routed", result["route_status"])
self.assertIn("WiringCutOut", result["route_track"]["carrier_kinds"])
self.assertEqual(0, result["collision_count"])
def test_check_routing_path_network_writes_diagnostic_for_unconnected_terminal(self):
_install_fake_freecad()

Loading…
Cancel
Save