From 1eb43a790d656fd309e1254751ebdc713066d87b Mon Sep 17 00:00:00 2001 From: umsangdon Date: Tue, 6 Oct 2026 17:38:14 +0900 Subject: [PATCH] =?UTF-8?q?fix(B07):=20=ED=9A=A1=EB=8B=A8=EB=A9=B4?= =?UTF-8?q?=EB=8F=84=20=EB=8B=A8=EB=A9=B4=20=EB=B8=94=EB=A1=9D=20=ED=85=8C?= =?UTF-8?q?=EB=91=90=EB=A6=AC=20=EA=B0=84=EA=B2=A9=201=20mm=20=E2=80=94=20?= =?UTF-8?q?=ED=95=9C=20=EC=9E=A5=EC=97=90=20=EB=8D=94=20=EB=8B=B4=EC=9D=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 테두리 여유 4 mm · 위아래 덧 여백 5 mm 제거 → 테두리 ↔ 그림 1 mm(CROSS_BORDER_PAD_MM) - 장 배치(Sheet.py)와 단독 도면(Engine_Cad.py) 같은 상수 - 검증_sub4 첫 장 칸 168×172 → 162×156 mm · 담을 수 8 → 12 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_013rJwJMVL4EE31y77TB11AP --- .../B07_DesignDetail_Engine_Cad.py | 11 +++--- .../B07_DesignDetail_Engine_Cad_Sheet.py | 5 +-- resources/tester/test_b07_cross_sheet_pad.py | 34 +++++++++++++++++++ 3 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 resources/tester/test_b07_cross_sheet_pad.py diff --git a/B07_DesignDetail/B07_DesignDetail_Engine_Cad.py b/B07_DesignDetail/B07_DesignDetail_Engine_Cad.py index 04b121aaf..294db5abe 100644 --- a/B07_DesignDetail/B07_DesignDetail_Engine_Cad.py +++ b/B07_DesignDetail/B07_DesignDetail_Engine_Cad.py @@ -386,6 +386,8 @@ def _cross_line_entities( CROSS_MM = 1000.0 / DRAWING_SCALE_CROSS # 단면을 그리는 가로 범위: 설계선(절·성토)·구조물이 원지반과 갈라지는 구간 + 여유(m). CROSS_SECTION_MARGIN_M = 1.5 +# 단면 블록 테두리 ↔ 안쪽 그림 간격(mm) — 한 장에 최대한 많이 담는다. +CROSS_BORDER_PAD_MM = 1.0 # 원지반과 "만난다"고 볼 표고 차이(m) — 이보다 작으면 붙어 있는 것으로 본다. _TOUCH_TOLERANCE_M = 0.02 @@ -507,7 +509,7 @@ def build_cross_drawing( # 표는 단면 중심 아래에 붙인다 (좌표는 mm). 그리는 창이 좌우 비대칭이면 # 단면 중심이 원점과 어긋나므로 표도 같은 중심을 쓴다. center_x = ox + (x0 + x1) / 2.0 * CROSS_MM - half_height = own_half_height * CROSS_MM + 5.0 + half_height = own_half_height * CROSS_MM table_bottom = oy - half_height if quantity_table is not None: table_top = oy - half_height - 8.0 @@ -520,10 +522,11 @@ def build_cross_drawing( if cell_frame is not None: frame_left, frame_bottom, frame_right, frame_top = cell_frame else: - frame_x = max((x1 - x0) / 2.0 * CROSS_MM + 4.0, cross_table_width() / 2.0 + 4.0) + pad = CROSS_BORDER_PAD_MM + frame_x = max((x1 - x0) / 2.0 * CROSS_MM + pad, cross_table_width() / 2.0 + pad) frame_left, frame_right = center_x - frame_x, center_x + frame_x - frame_top = oy + half_height + 4.0 - frame_bottom = table_bottom - 4.0 + frame_top = oy + half_height + pad + frame_bottom = table_bottom - pad corners = [ (frame_left, frame_bottom), (frame_right, frame_bottom), diff --git a/B07_DesignDetail/B07_DesignDetail_Engine_Cad_Sheet.py b/B07_DesignDetail/B07_DesignDetail_Engine_Cad_Sheet.py index 17b072707..73e91308c 100644 --- a/B07_DesignDetail/B07_DesignDetail_Engine_Cad_Sheet.py +++ b/B07_DesignDetail/B07_DesignDetail_Engine_Cad_Sheet.py @@ -11,6 +11,7 @@ from typing import Any from B05_Profile.B05_Profile_Engine_Sections import cross_key from B07_DesignDetail.B07_DesignDetail_Engine_Cad import ( + CROSS_BORDER_PAD_MM, CROSS_MM, CROSS_TABLE_LAYER_ID, DESIGN_LAYER_ID, @@ -44,7 +45,7 @@ CROSS_SHEET_ID = re.compile(r"cross_s(\d{2,}(?:\.\d{2})?)m?") # 블록 사이 여백(mm)과 테두리 여유 — build_cross_drawing의 테두리 값과 맞춘다. # 여백 0 = 이웃 칸의 테두리가 맞닿는다(2026-09-04 사용자 지시 — 박스 사이 간격 제거). _BLOCK_GAP_MM = 0.0 -_BORDER_PAD_MM = 4.0 +_BORDER_PAD_MM = CROSS_BORDER_PAD_MM def _design_points(design_line: list[Any] | None) -> list[tuple[float, float]]: @@ -72,7 +73,7 @@ def section_block_size( x0, x1 = _section_window(ground, design) ground_clipped = _clip_polyline(ground, x0, x1) ys = [y for _x, y in ground_clipped] + [y for x, y in design if x0 <= x <= x1] - half_height = ((max(ys) - min(ys)) / 2.0 if ys else 5.0) * CROSS_MM + 5.0 + half_height = ((max(ys) - min(ys)) / 2.0 if ys else 5.0) * CROSS_MM width = 2.0 * max( (x1 - x0) / 2.0 * CROSS_MM + _BORDER_PAD_MM, diff --git a/resources/tester/test_b07_cross_sheet_pad.py b/resources/tester/test_b07_cross_sheet_pad.py new file mode 100644 index 000000000..68e392445 --- /dev/null +++ b/resources/tester/test_b07_cross_sheet_pad.py @@ -0,0 +1,34 @@ +"""B07 횡단면도 — 단면 블록 테두리 ↔ 안쪽 그림 간격 1 mm (59-1).""" + +import pytest + +from B07_DesignDetail.B07_DesignDetail_Engine_Cad import ( + CROSS_BORDER_PAD_MM, + FRAME_LAYER_ID, + build_cross_drawing, +) +from B07_DesignDetail.B07_DesignDetail_Engine_Cad_Sheet import section_block_size +from B07_DesignDetail.B07_DesignDetail_Engine_Template import entities_bbox + +_SOURCE = { + "chainage_m": 20.0, + "samples": [ + {"valid": True, "offset_m": float(x), "elevation_m": 100.0 + 0.3 * x} + for x in range(-10, 11) + ], +} + + +def test_frame_hugs_section_by_one_mm() -> None: + drawing = build_cross_drawing(_SOURCE, "cross_00020m", None, None, None, "") + lines = [e for e in drawing["entities"] if e.get("layerId") != FRAME_LAYER_ID] + frame = [e for e in drawing["entities"] if e.get("layerId") == FRAME_LAYER_ID] + min_x, min_y, max_x, max_y = entities_bbox(lines) + f_min_x, f_min_y, f_max_x, f_max_y = entities_bbox(frame) + assert CROSS_BORDER_PAD_MM == 1.0 + assert f_max_y - max_y == pytest.approx(1.0) + assert min_y - f_min_y == pytest.approx(1.0) + # 표 없는 블록 크기 = 테두리 크기 + width, height = section_block_size(_SOURCE, None, with_table=False) + assert height == pytest.approx(f_max_y - f_min_y) + assert width == pytest.approx(f_max_x - f_min_x)