qcast-front/docs/plans/2026-07-08-passivity-movement-roofline-fix.md
Jaeyoung Lee 2eaabf87f4 [지붕선] fix: 수동설정 외곽 지붕선 생성 + 동선이동 폴리곤 잔존 수정
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 14:51:26 +09:00

7.4 KiB

수동설정 & 동선이동/형올림내림 외곽 지붕선/폴리곤 숨김 정합 — 구현 계획

For agentic workers: 이 계획은 task 단위로 실행한다. 각 step 은 checkbox(- [ ])로 추적한다. 검증 방식: 이 저장소는 test runner 가 없다(CLAUDE.md). 각 task 는 yarn dev 컴파일 성공 + 런타임 재현 체크리스트로 검증한다. 커밋은 재영이 나중에 일괄 수행 — 이 계획은 커밋 step 을 두지 않는다.

Goal: 지붕형상 수동설정과 동선이동/형올림내림 이후에도 원본 지붕 폴리곤이 화면에 남지 않고, 외곽 지붕선(파란 QLine)만 보이도록 정합한다.

Architecture: 설계 근거는 docs/plans/2026-06-01-skeleton-roofline-edit-design.md §11. 두 지점을 수정한다 — (1) 수동설정은 중복 drawRoofPolygon 호출을 제거하고 최종 roof 에 splitRoofLinesToInnerLines 를 직접 호출, (2) 동선이동/형올림내림은 팝업 cleanup 의 restoreLineStyles 가 폴리곤 stroke 를 파란색으로 되살리던 것을 transparent 로 정합.

Tech Stack: Next.js 14, Fabric.js 5.5.2, @/util/qpolygon-utilssplitRoofLinesToInnerLines.


파일 구조

파일 책임 변경
src/hooks/roofcover/useRoofShapePassivitySetting.js 지붕형상 수동설정 import 추가 + handleLineToPolygon 중복 제거 + split 호출
src/hooks/roofcover/useMovementSetting.js 동선이동/형올림내림 restoreLineStyles 1줄 정합

전제(확정된 사실):

  • splitRoofLinesToInnerLines(roof, innerLines, canvas, textMode, opts={})@/util/qpolygon-utilsexport 되어 있다.
  • innerLines 빈 배열로 부르면 분할점이 없어 각 roof.lines 변이 통짜 외곽 지붕선(drawRoofLine)으로 그려지고, 함수 끝(:5775)에서 roof.set({ stroke: 'transparent' }) 로 원본 폴리곤을 숨긴다. 마루/추녀는 생성되지 않는다(수동설정 요구사항).
  • drawRoofPolygonmakePolygon(useMode.js:1387 canvas.add) 경유로 roof 를 캔버스에 추가하고 기존 roof 를 제거하지 않는다. 그래서 수동설정의 :288·:296 이중 호출은 roof 2개를 남긴다(중복 확정).

Task 1: 수동설정 — 중복 drawRoofPolygon 제거 + split 직접 호출

Files:

  • Modify: src/hooks/roofcover/useRoofShapePassivitySetting.js (import 라인, handleLineToPolygon :286-298)

  • Step 1: splitRoofLinesToInnerLines import 추가

파일 상단 import 블록(:1-13)에 아래 한 줄을 추가한다(기존 @/util/canvas-util import 아래 등 적절한 위치):

import { splitRoofLinesToInnerLines } from '@/util/qpolygon-utils'
  • Step 2: handleLineToPolygon 의 중복 세트 제거 + split 삽입

현재 코드(:286-298):

    // 완료 한 경우에는 지붕까지 그려줌
    addPitchTextsByOuterLines()
    const roof = drawRoofPolygon(wall)
    addLengthText(roof)

    if (isFix.current) {
      // 완료 한 경우에는 지붕까지 그려줌
      addPitchTextsByOuterLines()
      // 지붕 그리기 직전(라인 세팅 완료) 상태를 스냅샷 → undo 시 지붕이 그려지기 전 화면으로 복귀
      saveSnapshot(null, { force: true })
      const roof = drawRoofPolygon(wall)
      addLengthText(roof)
    }

아래로 교체한다(블록 밖 첫 세트 3줄 제거, if 블록 내 split 2줄 추가):

    if (isFix.current) {
      // 완료 한 경우에는 지붕까지 그려줌
      addPitchTextsByOuterLines()
      // 지붕 그리기 직전(라인 세팅 완료) 상태를 스냅샷 → undo 시 지붕이 그려지기 전 화면으로 복귀
      saveSnapshot(null, { force: true })
      const roof = drawRoofPolygon(wall)
      addLengthText(roof)
      // [2026-07-08] 지붕모양(roof.lines)을 따라 외곽 지붕선 생성 + 원본 폴리곤 숨김(transparent).
      //   innerLines 빈 배열 → 분할점 없어 각 변이 통짜 지붕선(drawRoofLine). 마루/추녀는 생성 안 함(수동설정은 외곽선만).
      roof.innerLines = roof.innerLines || []
      splitRoofLinesToInnerLines(roof, roof.innerLines, canvas, 'plane')
    }

근거: isFix=false 경로는 이 지점 이전 :228에서 롤백 후 return 하므로 제거한 첫 세트는 저장 경로에서만 실행되던 중복이다. 제거로 saveSnapshot 이 비로소 '지붕 그리기 전' 상태를 찍게 되어 주석과 코드가 일치한다.

  • Step 3: dev 컴파일 검증

Run: yarn dev Expected: 컴파일 에러 없이 로컬 서버 기동(localhost:3000). splitRoofLinesToInnerLines import 미해결/문법 에러 없음. (주의: dev 실행 중 yarn build 금지 — .next 오염.)

  • Step 4: 런타임 재현 검증 (수동설정)

브라우저에서 지붕형상 수동설정으로 외곽선 타입을 지정하고 완료. Expected:

  • 외곽 지붕선(파란 QLine)이 그려진다.
  • 검은/파란 원본 폴리곤 외곽선이 남지 않는다(겹친 roof 없음).
  • 마루/추녀는 생성되지 않는다(의도).
  • 이후 지붕면 할당 메뉴로 정상 전환(:216).

Task 2: 동선이동/형올림내림 — restoreLineStyles 폴리곤 stroke 정합

Files:

  • Modify: src/hooks/roofcover/useMovementSetting.js:222

  • Step 1: cleanup 의 폴리곤 stroke 복원값을 transparent 로 변경

현재 restoreLineStyles(:219-224):

  const restoreLineStyles = () => {
    const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
    roofs.forEach((roof) => {
      roof.set({ stroke: '#1083E3' })
      roof.innerLines.forEach((line) => line.set({ selectable: true, strokeWidth: 2, stroke: '#1083E3' }))
    })

:222 한 줄만 변경한다:

      roof.set({ stroke: 'transparent' })

roof.innerLines(:223) 의 파란색·selectable 복원은 그대로 유지한다(지붕선은 파란색이 맞음). 근거: 평상 상태의 원본 폴리곤 stroke 는 split(:5775)이 만든 transparent 이며, cleanup 이 이를 파란색으로 되살리던 것이 폴리곤이 항상 보이던 원인이다.

  • Step 2: dev 컴파일 검증

Run: yarn dev Expected: 컴파일 에러 없음.

  • Step 3: 런타임 재현 검증 (동선이동/형올림내림)

브라우저에서:

  • 동선이동(FLOW_LINE) 마루 이동 저장 → 팝업 닫힘 후 원본 폴리곤이 안 보이고 외곽 지붕선(파란)만 남는다.
  • 형올림내림(UP_DOWN) 저장 → 동일하게 폴리곤 안 보임.
  • 취소(이동 없이 팝업 닫기) → 폴리곤 안 보임(진입 시 :90 에서 검게 만든 stroke 가 올바르게 원복).

최종 회귀 검증

  • 템플릿설정(useRoofShapeSetting) 4경로 회귀: 용마루/박공/한쪽흐름/변별 지붕을 템플릿으로 생성 → 외곽 지붕선·폴리곤 숨김 기존과 동일(회귀 없음).
  • 동선이동 2회 연속: 마루이동 → 다시 마루이동 시 지붕선/폴리곤 정상.
  • 수동설정 → 동선이동 연계: 수동설정으로 만든 지붕을 동선이동/형올림내림 → 폴리곤 안 보임 유지.

범위 밖 (YAGNI)

  • drawHelpLine 최상위 폴리곤 숨김 일원화 — 제외(설계 §11-4). 두 버그와 직접 무관.
  • addPitchTextsByOuterLines 는 Task 1 에서 첫 세트 제거로 자연히 1회만 남는다. 별도 정리 불필요.