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)