fix(526-1): B07 횡단 장 인쇄 칸선 지움 · 칸마다 안내선 · 처음 맞춤 작도 영역까지

- 횡단 장 칸 격자선(도각 층 인쇄 개체) 지움 — 칸은 화면 안내선 겹판(guide.cells · 단면마다 점선)
  · 안내선 숨기기에 함께 꺼짐 · 넘친 칸 붉은 틀은 그대로
- 옛 확정 · 저장본 장은 열 때 칸선만 걷고 칸 안내선은 지금 배치로(refresh_saved_sheet)
- CAD 처음 맞춤 · 전체 맞춤 = 내용 + 작도 영역(가이드) — 표준 횡단도가 내용에만 확대돼
  도면 한 장 안 자리가 안 보이던 흠
- 낡은 시험 고침: test_169 칸선 단언 → 칸선 없음 + 칸 안내선 · test_212_3 「남는 검은 선 =
  인쇄 칸선 지우지 않음」(212-3 결정) → 요구 343-4 로 칸선 지움 · guide-area 시험 칸 그리기

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-25 14:39:18 +09:00
co-authored by Claude Opus 5.5
parent 624a3e0aaa
commit a2c3c0fc1f
12 changed files with 140 additions and 80 deletions
+37 -21
View File
@@ -4,7 +4,7 @@
못박는 것
- 169-1 그림칸 = 작도 영역 그대로(여백 없음) · 도각 편집이 영역을 싣고 · 저장(어긋나면 옛 값).
- 169-1 도면 좌표 가이드 영역 = 도각 bbox ↔ 양식 bbox 로 옮긴 영역 · 도각 아닌 것(블록 틀)이면 None.
- 169-2 횡단 장 = 칸 격자선(열 + 1 · 행 + 1 · 칸 경계) · 장 안 블록 테두리 없음 · 큰 단면 → 넘친 칸.
- 169-2 · 526-1 횡단 장 = 인쇄 칸선 · 블록 테두리 없음 · 칸 = 안내선(단면마다) · 큰 단면 → 넘친 칸.
- 169-4 구조물 도각(외곽 좌하단 0,0) 응답에 영역.
"""
@@ -20,7 +20,11 @@ from B07_DesignDetail.B07_DesignDetail_Engine_Cad import (
FRAME_LAYER_ID,
build_cross_drawing,
)
from B07_DesignDetail.B07_DesignDetail_Engine_Cad_Sheet import build_cross_sheet, plan_cross_sheets
from B07_DesignDetail.B07_DesignDetail_Engine_Cad_Sheet import (
build_cross_sheet,
plan_cross_sheets,
refresh_saved_sheet,
)
from B07_DesignDetail.B07_DesignDetail_Router import _drawing_guide
from M02_MasterTemplete.M02_MasterTemplete_Router_Drawing import structure_frame
@@ -69,37 +73,49 @@ def test_frame_edit_loads_and_saves_area(tmp_path):
assert 'request.drawing.get("drawing_area")' in router and "area=area" in router
def test_cross_sheet_grid_lines_no_block_border_and_guide_area():
def test_cross_sheet_no_grid_lines_no_block_border_and_guide_cells():
engine.use_project_templates(None)
w, h = engine.usable_area()
sources = [_source(i * 20.0, 0.05, 6) for i in range(3)]
sheet, drawing = _sheet(sources, {"default": [3, 2]})
by_id = {e["id"]: e for e in drawing["entities"]}
def line(name: str) -> tuple[dict, dict]:
entity = by_id[str(uuid5(_POLY_NS, f"{sheet['id']}:{FRAME_LAYER_ID}:grid-{name}"))]
assert entity["layerId"] == FRAME_LAYER_ID
shape = entity["children"][0]["shapeData"]
return shape["startPoint"], shape["endPoint"]
# 격자선 = 세로 열 + 1 · 가로 행 + 1 · 칸 경계 자리 · 그림칸 끝에서 끝까지
for i in range(3 + 1):
a, b = line(f"v{i}")
assert a["x"] == b["x"] == pytest.approx(-w / 2 + w * i / 3)
assert (a["y"], b["y"]) == pytest.approx((-h / 2, h / 2))
for j in range(2 + 1):
a, b = line(f"h{j}")
assert a["y"] == b["y"] == pytest.approx(-h / 2 + h * j / 2)
assert (a["x"], b["x"]) == pytest.approx((-w / 2, w / 2))
assert str(uuid5(_POLY_NS, f"{sheet['id']}:{FRAME_LAYER_ID}:grid-v4")) not in by_id
# 장 안 블록 테두리 없음(측점 한 장 테두리와 같은 id 자리)
# 인쇄 칸선 없음(526-1 · 옛 169-2 `:grid-v0` …) · 장 안 블록 테두리 없음
for name in ("v0", "v1", "h0", "h1"):
assert str(uuid5(_POLY_NS, f"{sheet['id']}:{FRAME_LAYER_ID}:grid-{name}")) not in by_id
for source in sources:
seed = f"{sheet['id']}:{source['chainage_m']}:{FRAME_LAYER_ID}"
assert str(uuid5(_POLY_NS, seed)) not in by_id
# 가이드 영역(도면 좌표) = 그림칸 그대로 · 넘침 없음
# 칸 = 화면 안내선 — 단면마다 하나 · 좌하단 → 위 → 오른쪽 열
cw, ch = w / 3, h / 2
expected = [
[-w / 2, -h / 2, -w / 2 + cw, -h / 2 + ch],
[-w / 2, -h / 2 + ch, -w / 2 + cw, h / 2],
[-w / 2 + cw, -h / 2, -w / 2 + 2 * cw, -h / 2 + ch],
]
assert drawing["guide_cells"] == [pytest.approx(cell) for cell in expected]
# 가이드 영역(도면 좌표) = 그림칸 그대로 · 넘침 없음 · 칸 = 단면 수
guide = _drawing_guide(drawing)
assert guide["area"] == pytest.approx([-w / 2, -h / 2, w / 2, h / 2], abs=1e-3)
assert guide["marks"] == [] and drawing["overflow_cells"] == []
assert guide["cells"] == drawing["guide_cells"]
def test_saved_sheet_strips_grid_lines_and_gets_cells():
# 옛 확정 · 저장본(칸선 품음) — 칸선만 걷고 칸 안내선은 지금 배치로(526-1)
engine.use_project_templates(None)
sources = [_source(i * 20.0, 0.05, 6) for i in range(2)]
sheet, drawing = _sheet(sources, {"default": [2, 2]})
grid = [
{"id": str(uuid5(_POLY_NS, f"{sheet['id']}:{FRAME_LAYER_ID}:grid-{name}"))}
for name in ("v0", "v2", "h1")
]
saved = {"entities": drawing["entities"] + grid}
refresh_saved_sheet(sheet["id"], saved, lambda: [sheet])
assert saved["entities"] == drawing["entities"]
assert saved["guide_cells"] == drawing["guide_cells"] and len(saved["guide_cells"]) == 2
refresh_saved_sheet("cross_s99999m", saved, lambda: [sheet]) # 지금 배치에 없는 장 = 칸 없음
assert saved["guide_cells"] == []
def test_big_section_marks_its_cell():
+2 -2
View File
@@ -4,7 +4,7 @@
못박는 것
- 횡단 장 · 측점 한 장의 원지반 층은 안 잠김(종단은 그대로 잠김).
- 측점마다 groupId 하나(원지반 · 계획선 · 표 · 글 전부) · 측점끼리 다름.
- 칸 격자선 · 도각엔 groupId 없음.
- 도각엔 groupId 없음.
- cross_placements 의 group_id = 그 측점 엔티티 값(화면 덧그림이 같은 묶음).
"""
@@ -78,7 +78,7 @@ def test_측점마다_groupId_하나() -> None:
types = {e["type"] for e in members}
ground = any(e["type"] == "PolyLine" and e["lineColor"] == GROUND_COLOR for e in members)
assert ground and "Table" in types and "Text" in types
# 격자선 · 도각은 묶지 않음
# 도각은 묶지 않음
assert all("groupId" not in e for e in drawing["entities"] if e["layerId"] == FRAME_LAYER_ID)
assert all(e["layerId"] != FRAME_LAYER_ID for e in grouped)
@@ -6,16 +6,14 @@
· [안내선 숨기기](부르는 쪽).
- 단추 · 숫자 칸 · 이름 = 좌측 패널 공용 양식(269 `.ui-panel-form`) · 한 줄 안 같은 너비.
- 옛 한 줄 감기(flex-wrap) · 숫자 칸 48px 고정 없음.
- [안내선 숨기기] 뒤 남는 검은 선 = 인쇄 칸선(도각 층 도면 개체 · 회청 `#8ea0b5`
· 밝은 바탕에서 짙게 그려짐) — 안내선(겹판)과 다른 것이라 지우지 않음 · 단추는 겹판만 끔.
- 인쇄 칸선 없음(526-1 · 옛 「남는 검은 선」) — 칸은 안내선 겹판(단면마다 점선)이라
[안내선 숨기기] 뒤 남는 선 없음 · 단추는 겹판만 끔.
"""
import re
from pathlib import Path
from B07_DesignDetail.B07_DesignDetail_Engine_Cad import FRAME_LAYER_ID, TABLE_LINE_COLOR
from B07_DesignDetail.B07_DesignDetail_Engine_Cad_Sheet import _grid_lines
from B07_DesignDetail.B07_DesignDetail_Engine_Template import use_project_templates
from B07_DesignDetail import B07_DesignDetail_Engine_Cad_Sheet as sheet_engine
ROOT = Path(__file__).resolve().parents[2]
CSS = (ROOT / "B07_DesignDetail/B07_DesignDetail_UI_Style.css").read_text(encoding="utf-8")
@@ -63,14 +61,11 @@ def test_한_줄에_한_일_같은_너비():
assert "controls.append(deps.cross.guideToggle);" in SETTINGS
def test_남는_검은_선은_인쇄_칸선_지우지_않음():
use_project_templates(None)
lines = _grid_lines("cross_s00000m", 4, 4)
assert len(lines) == 10 # 세로 5 · 가로 5 그대로
assert all(e["layerId"] == FRAME_LAYER_ID for e in lines)
assert all(e["lineColor"] == TABLE_LINE_COLOR == "#8ea0b5" for e in lines)
# 안내선 단추는 겹판(점선 영역 + 붉은 틀)만 — 도면 개체를 안 건드림
def test_인쇄_칸선_없음_칸은_안내선_겹판():
assert not hasattr(sheet_engine, "_grid_lines") # 526-1 — 칸선 도면 개체 없음
# 칸 · 점선 영역 · 붉은 틀 모두 겹판 — 숨김이면 안 그림 · 도면 개체를 안 건드림
draw = GUIDE[GUIDE.index("export function drawGuide") :]
draw = draw[: draw.index("\n}\n")]
assert "if (!guide || !guideVisible) return;" in draw
assert "guide.cells" in draw
assert "getEntities" not in draw and "setEntities" not in draw
@@ -4,7 +4,7 @@
못박는 것
- 212-1 옛 확정 장(원지반 층 잠금째 저장)도 열 때 원지반 잠금 풂 · 측점 층 없으면 stale_layers.
- 212-2 장의 측점마다 층 하나(`b08-station-{측점}` · 이름 「횡단 {제목}」) = 원지반 · 계획선 ·
암 그림(자식 선까지) · 표 · 글은 수량표 층 · 격자선 · 도각은 도각 층 · 종류 층 없음.
암 그림(자식 선까지) · 표 · 글은 수량표 층 · 도각은 도각 층 · 종류 층 없음.
- 개체 id 는 그대로(층만 바뀜) · placement 에 layer_id · design_ids(화면 덧그림 갈아 끼우기).
- DXF 층 이름 = 측점 층 id 그대로(금지 문자 없음).
- 화면 덧그림도 측점 층 · design_ids 로 서버 설계선 걷음(소스 확인 · typecheck 는 따로).