fix(understand): the pipe network's tolerance follows the P&ID's unit, and a dropped stub is said
pipe_takeoff merged line ends closer than tol = 1.0 drawing units and silently dropped any segment shorter than that. On a millimetre P&ID that is 1 mm. On a metre drawing it is a metre: ends a metre apart were merged and every pipe under a metre disappeared from the totals, with no warning. The review of the network engine found this. - tol now defaults to 1 mm in the unit the P&ID's geometry implies: 1.0 on a millimetre drawing, 0.001 on a metre one. A tol the caller gives is used as given. - build_network counts the segments that collapse to a point (stats.segments_below_tol), and pipe_rows turns a non-zero count into a warning naming the tolerance. A new wire test builds a metre P&ID with a 0.6 m pipe and a 5 m pipe. Before this change the takeoff said 5.0 m; now it says 5.6 m. The network test checks that a sub-tolerance stub is counted. Registry, packs, aliases and every track H suite: 472 passed. The inventory matches the live surface. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
fb2953c324
commit
c4759e696d
@@ -103,6 +103,14 @@ def test_ends_within_tol_merge_into_one_run():
|
||||
assert run.ends == ((0.0, 0.0), (2000.0, 0.0))
|
||||
|
||||
|
||||
def test_a_segment_shorter_than_tol_is_counted_when_it_is_dropped():
|
||||
# a 0.5-unit stub collapses to one vertex at tol 1.0: gone from the network,
|
||||
# but never silently - stats say how many went
|
||||
result = net(line("1", (0.0, 0.0), (1000.0, 0.0)), line("2", (2000.0, 0.0), (2000.5, 0.0)))
|
||||
assert result["stats"]["segments_below_tol"] == 1
|
||||
assert net(line("1", (0.0, 0.0), (1000.0, 0.0)))["stats"]["segments_below_tol"] == 0
|
||||
|
||||
|
||||
def test_a_branch_ending_on_a_header_is_a_t_junction():
|
||||
result = net(line("1", (0.0, 0.0), (2000.0, 0.0)), line("2", (1000.0, 0.0), (1000.0, 800.0)))
|
||||
(run,) = result["runs"]
|
||||
|
||||
@@ -37,6 +37,25 @@ def plant(tmp_path):
|
||||
return build_plant_pair(tmp_path)
|
||||
|
||||
|
||||
async def test_a_metre_pid_keeps_a_pipe_shorter_than_one_drawing_unit(client, tmp_path):
|
||||
# The junction tolerance defaults to 1 mm in the unit the P&ID's geometry
|
||||
# implies. A fixed 1.0 would be a metre here: the 0.6 m pipe would collapse
|
||||
# to a point and vanish from the totals.
|
||||
import ezdxf
|
||||
|
||||
doc = ezdxf.new(setup=False)
|
||||
doc.header["$INSUNITS"] = 6 # metres
|
||||
msp = doc.modelspace()
|
||||
msp.add_line((0.0, 0.0), (0.6, 0.0), dxfattribs={"layer": "PRODUCT"})
|
||||
msp.add_line((10.0, 0.0), (15.0, 0.0), dxfattribs={"layer": "PRODUCT"})
|
||||
msp.add_text("NOTES", height=0.25, dxfattribs={"layer": "TEXT"}).set_placement((0.0, 1.0))
|
||||
path = tmp_path / "metre_pid.dxf"
|
||||
doc.saveas(path)
|
||||
result = (await client.call_tool("pipe_takeoff", {"pid_path": str(path)})).structured_content
|
||||
assert result["units"]["pid"]["inferred"] == "m"
|
||||
assert result["totals"]["net_m"] == pytest.approx(5.6) # 0.6 + 5.0
|
||||
|
||||
|
||||
async def test_pipe_takeoff_measures_on_the_layout_and_writes_the_workbook(client, plant, tmp_path):
|
||||
output = tmp_path / "takeoff.xlsx"
|
||||
arguments = {
|
||||
|
||||
Reference in New Issue
Block a user