feat: 支持线槽端部缩进配置

dev
Zhaowenlong 3 weeks ago
parent f653549366
commit 2019f54051

@ -195,8 +195,11 @@ QetAutoRouteDiagnosticsJson
QetRoutingSourceKind = "WireDuct"
QetRoutingObstacleMode = "PassThrough"
QetRouteCarrierName = <generated carrier name>
QetWireDuctEndMarginMm = 20.0
```
`QetWireDuctEndMarginMm` 表示自动生成的线槽中心线距离线槽两端缩进多少毫米。默认值用于避开线槽端盖/端部开口;如果某个线槽很短,或现场希望中心路径更靠近端部,可以在 FreeCAD 属性面板中按对象调整。
## 4. 算法设计
### 4.1 路由网络构建
@ -425,6 +428,7 @@ tests/python/freecad_exchange_auto_routing_test.py
25. `WiringCutOut` 会在穿孔方向外扩虚拟路径,用于桥接开孔两侧附近的线槽或支撑面网络,并支持通过 `QetWiringCutOutBridgeExtensionMm` 按对象调整外扩距离。
26. `QetRouteTrackJson` 会在 carrier 有源对象元数据时保存 `source_name`、`source_label`、`source_kind`,方便核对导线实际走过的线槽、过线孔或支撑面。
27. 批量布线报告会显示一条路径示例,列出首条可追踪导线经过的源对象标签。
28. 线槽源对象支持通过 `QetWireDuctEndMarginMm` 按对象调整中心路径端部缩进距离。
已完成 FreeCAD smoke

@ -502,7 +502,17 @@ def _route_carrier_capacity_value(obj, default=1):
return int(default or 1)
def _set_wire_duct_source_semantics(source):
def _wire_duct_end_margin_value(source, default=DEFAULT_WIRE_DUCT_MARGIN):
try:
value = float(getattr(source, "QetWireDuctEndMarginMm", default) or 0.0)
except Exception:
value = float(default or 0.0)
if value < 0.0:
return 0.0
return value
def _set_wire_duct_source_semantics(source, end_margin=DEFAULT_WIRE_DUCT_MARGIN):
if source is None:
return
TerminalObjects.ensure_string_property(
@ -525,6 +535,12 @@ def _set_wire_duct_source_semantics(source):
"How many routed wires can reuse generated wire duct segments before detouring is preferred",
_route_carrier_capacity_value(source, default=1),
)
_ensure_float_property(
source,
"QetWireDuctEndMarginMm",
"How far generated wire duct centerlines stay inside each duct end",
_wire_duct_end_margin_value(source, default=end_margin),
)
def _set_support_surface_source_semantics(source):
@ -1463,7 +1479,14 @@ def _wire_duct_centerline_from_bbox(bbox, margin=DEFAULT_WIRE_DUCT_MARGIN, min_a
).get("centerline", [])
def _sync_wire_duct_source_carriers(doc, source, spec, project_uuid="", capacity=1):
def _sync_wire_duct_source_carriers(
doc,
source,
spec,
project_uuid="",
capacity=1,
end_margin=DEFAULT_WIRE_DUCT_MARGIN,
):
carriers = _live_source_carriers(doc, source)
if not carriers:
return False
@ -1489,7 +1512,7 @@ def _sync_wire_duct_source_carriers(doc, source, spec, project_uuid="", capacity
updated.append(carrier)
if updated:
_mark_wire_duct_source(source, updated[0], updated)
_mark_wire_duct_source(source, updated[0], updated, end_margin=end_margin)
try:
doc.recompute()
except Exception:
@ -1627,11 +1650,11 @@ def _remember_source_carriers(source, carriers):
)
def _mark_wire_duct_source(source, carrier, carriers=None):
def _mark_wire_duct_source(source, carrier, carriers=None, end_margin=DEFAULT_WIRE_DUCT_MARGIN):
if source is None:
return
try:
_set_wire_duct_source_semantics(source)
_set_wire_duct_source_semantics(source, end_margin=end_margin)
if carrier is not None:
TerminalObjects.ensure_string_property(
source,
@ -1876,9 +1899,10 @@ def create_wire_duct_carriers_from_document(
bbox = _bound_box_from_object(source)
if bbox is None:
continue
source_margin = _wire_duct_end_margin_value(source, default=margin)
spec = _wire_duct_centerline_spec_from_bbox(
bbox,
margin=margin,
margin=source_margin,
min_aspect=min_aspect,
)
points = spec.get("centerline", [])
@ -1892,6 +1916,7 @@ def create_wire_duct_carriers_from_document(
spec,
project_uuid=project_uuid,
capacity=capacity,
end_margin=source_margin,
):
continue
carrier = create_route_carrier(
@ -1917,7 +1942,7 @@ def create_wire_duct_carriers_from_document(
)
source_created.append(open_end_carrier)
created.append(open_end_carrier)
_mark_wire_duct_source(source, carrier, source_created)
_mark_wire_duct_source(source, carrier, source_created, end_margin=source_margin)
return created
@ -2247,9 +2272,10 @@ def create_wire_duct_carriers_from_selection(
bbox = _bound_box_from_object(source)
if bbox is None:
continue
source_margin = _wire_duct_end_margin_value(source, default=margin)
spec = _wire_duct_centerline_spec_from_bbox(
bbox,
margin=margin,
margin=source_margin,
min_aspect=min_aspect,
)
points = spec.get("centerline", [])
@ -2263,6 +2289,7 @@ def create_wire_duct_carriers_from_selection(
spec,
project_uuid=project_uuid,
capacity=capacity,
end_margin=source_margin,
):
continue
carrier = create_route_carrier(
@ -2288,7 +2315,7 @@ def create_wire_duct_carriers_from_selection(
)
source_created.append(open_end_carrier)
created.append(open_end_carrier)
_mark_wire_duct_source(source, carrier, source_created)
_mark_wire_duct_source(source, carrier, source_created, end_margin=source_margin)
return created

@ -1648,6 +1648,26 @@ class AutoRoutingTest(unittest.TestCase):
self.assertEqual("PassThrough", duct.QetRoutingObstacleMode)
self.assertEqual([(20.0, 0.0, 15.0), (100.0, 0.0, 15.0)], [(p.x, p.y, p.z) for p in carrier.Points])
def test_wire_duct_source_end_margin_controls_generated_centerline_length(self):
_install_fake_freecad()
terminal_objects, _wiring_objects, routing_network, _auto_routing = _reload_modules()
doc = FakeDocument()
terminal_objects.ensure_root_group(doc, "project-1")
duct = doc.addObject("Part::Feature", "WireDuctA")
duct.Label = "线槽A"
duct.Shape = FakeShape(FakeBoundBox(0, 120, -10, 10, 5, 25))
duct.QetWireDuctEndMarginMm = 5.0
created = routing_network.create_wire_duct_carriers_from_document(
doc,
project_uuid="project-1",
)
carrier = [item for item in created if item.QetRouteCarrierKind == "WireDuct"][0]
self.assertIn("QetWireDuctEndMarginMm", duct.PropertiesList)
self.assertEqual(5.0, duct.QetWireDuctEndMarginMm)
self.assertEqual([(5.0, 0.0, 15.0), (115.0, 0.0, 15.0)], [(p.x, p.y, p.z) for p in carrier.Points])
def test_wire_duct_source_capacity_is_copied_to_generated_carriers(self):
_install_fake_freecad()
terminal_objects, _wiring_objects, routing_network, _auto_routing = _reload_modules()

Loading…
Cancel
Save