feat(b07): 횡단도 표 위 CAD 칸 배치 · 없으면 옛 글 줄 (260-3)
- design.structure_note_cad 엔티티 = 범위 왼쪽 위를 표 왼쪽 · 윗변에 맞춤 · 표 층 · 배율 따름 - 표 · 테두리 · 시트 칸 높이 = 범위 높이 · 칸이 비면 아무것도 안 놓음 · 칸 없으면 옛 글 줄 - 시험 test_260_note_cad B07 몫 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TNMXVCZXMpHpVvqmFkeChL
This commit is contained in:
@@ -401,6 +401,96 @@ def _cross_note_entities(
|
||||
]
|
||||
|
||||
|
||||
# 표 위 CAD 칸(260-3) — B06 [상세] 빈 CAD(`design.structure_note_cad`) 엔티티를 표 왼쪽 위에 맞춤.
|
||||
# 칸이 있으면(엔티티가 비었어도) 옛 글 대신 이것 · 없으면 옛 글 줄 그대로.
|
||||
|
||||
|
||||
def cross_note_cad(design: dict[str, Any] | None) -> list[dict[str, Any]] | None:
|
||||
"""설계의 표 위 CAD 엔티티 — 칸이 없으면 None(옛 글 줄로)."""
|
||||
cad = design.get("structure_note_cad") if isinstance(design, dict) else None
|
||||
if not isinstance(cad, dict):
|
||||
return None
|
||||
entities = cad.get("entities")
|
||||
return [e for e in entities if isinstance(e, dict)] if isinstance(entities, list) else []
|
||||
|
||||
|
||||
def _text_width(label: str, font: float) -> float:
|
||||
"""글 폭 어림(mm) — 한글 · 한자 = 글자 크기 · 그 밖 = 0.6 배."""
|
||||
return sum(font if ord(char) >= 0x2E80 else 0.6 * font for char in label)
|
||||
|
||||
|
||||
def note_cad_bbox(entities: list[dict[str, Any]]) -> tuple[float, float, float, float] | None:
|
||||
"""CAD 칸 범위 (min_x, min_y, max_x, max_y) — 글은 기준점이 세로 가운데(CAD `textBaseline`)라
|
||||
글 높이 · 폭을 맞춤 쪽으로 더함 · 그 밖은 `entities_bbox`."""
|
||||
from B07_DesignDetail.B07_DesignDetail_Engine_Template import entities_bbox
|
||||
|
||||
boxes = []
|
||||
for entity in entities:
|
||||
shape = entity.get("shapeData") or {}
|
||||
base = shape.get("basePoint")
|
||||
if entity.get("type") == "Text" and isinstance(base, dict):
|
||||
options = shape.get("options") or {}
|
||||
font = float(options.get("fontSize") or 0.0)
|
||||
width = _text_width(str(shape.get("label") or ""), font)
|
||||
x, y = float(base["x"]), float(base["y"])
|
||||
left = {"center": x - width / 2.0, "right": x - width}.get(options.get("textAlign"), x)
|
||||
boxes.append((left, y - font / 2.0, left + width, y + font / 2.0))
|
||||
elif (box := entities_bbox([entity])) is not None:
|
||||
boxes.append(box)
|
||||
if not boxes:
|
||||
return None
|
||||
return (
|
||||
min(b[0] for b in boxes),
|
||||
min(b[1] for b in boxes),
|
||||
max(b[2] for b in boxes),
|
||||
max(b[3] for b in boxes),
|
||||
)
|
||||
|
||||
|
||||
def _on_layer(entity: dict[str, Any], layer_id: str) -> dict[str, Any]:
|
||||
entity["layerId"] = layer_id
|
||||
for child in entity.get("children") or []:
|
||||
_on_layer(child, layer_id)
|
||||
return entity
|
||||
|
||||
|
||||
def cross_note_block_height(design: dict[str, Any] | None, scale: float = 1.0) -> float:
|
||||
"""표 위 칸 높이(mm) — CAD 칸 = 범위 높이 × 배율 · 없으면 옛 글 줄 높이."""
|
||||
cad = cross_note_cad(design)
|
||||
if cad is None:
|
||||
return cross_note_height(cross_note_lines(design), scale)
|
||||
box = note_cad_bbox(cad)
|
||||
return (box[3] - box[1]) * scale if box else 0.0
|
||||
|
||||
|
||||
def cross_note_block_entities(
|
||||
drawing_id: str,
|
||||
design: dict[str, Any] | None,
|
||||
top: float,
|
||||
center_x: float = 0.0,
|
||||
scale: float = 1.0,
|
||||
) -> list[dict[str, Any]]:
|
||||
"""표 위 칸 엔티티 — CAD 칸 = 범위 왼쪽 위를 표 왼쪽 끝 · `top` 에 맞춰 옮김(× 배율 · 표 층 ·
|
||||
id `{도면}:notecad:{n}`) · 없으면 옛 글 줄(`_cross_note_entities`)."""
|
||||
cad = cross_note_cad(design)
|
||||
if cad is None:
|
||||
return _cross_note_entities(drawing_id, cross_note_lines(design), top, center_x, scale)
|
||||
box = note_cad_bbox(cad)
|
||||
if box is None:
|
||||
return []
|
||||
from B07_DesignDetail.B07_DesignDetail_Engine_Template import _transform_entity
|
||||
|
||||
left = center_x - _CROSS_TABLE_WIDTH * scale / 2.0
|
||||
dx, dy = left - box[0] * scale, top - box[3] * scale
|
||||
return [
|
||||
_on_layer(
|
||||
_transform_entity(entity, f"{drawing_id}:notecad:{index}", scale, dx, dy),
|
||||
CROSS_TABLE_LAYER_ID,
|
||||
)
|
||||
for index, entity in enumerate(cad)
|
||||
]
|
||||
|
||||
|
||||
def cross_table_width(scale: float = 1.0) -> float:
|
||||
"""수량 산출표 가로 폭(mm)."""
|
||||
return _CROSS_TABLE_WIDTH * scale
|
||||
|
||||
Reference in New Issue
Block a user