dev #931

Merged
ysCha merged 95 commits from dev into prd-deploy 2026-06-23 17:47:25 +09:00
2 changed files with 46 additions and 6 deletions
Showing only changes of commit 07f787670d - Show all commits

View File

@ -556,6 +556,12 @@ export function useCommonUtils() {
if (object.id) {
const group = canvas.getObjects().filter((obj) => obj.id === object.id)
group.forEach((obj) => canvas?.remove(obj))
// QLine 보조선은 lengthText 를 this.text(단수)에 저장해 아래 texts(배열) 제거에 안 걸린다.
// lengthText 는 parentId === line.id 로 연결되므로 parentId 매칭으로 함께 제거 (삭제 시 text 잔존 방지).
canvas
.getObjects()
.filter((obj) => obj.parentId === object.id && obj.name === 'lengthText')
.forEach((obj) => canvas?.remove(obj))
}
if (object.type === 'group') {

View File

@ -1628,9 +1628,10 @@ export const drawGableRoof = (roofId, canvas, textMode) => {
drawRoofPlane(backward)
})
roof.innerLines.push(...ridgeLines, ...innerLines)
// 처마선 innerLine 이 외곽선을 전담하므로 roof 원본 외곽(stroke)은 숨긴다.
// (박공은 split 공용 함수를 안 거치므로 여기서 직접 처리 — usePolygon.js 의 roof 기본 stroke:'black')
// 처마선 innerLine 이 외곽선/치수를 전담하므로 roof 원본 외곽(stroke) 숨김 + 지붕선 치수(roof lengthText) 제거.
// 외벽선(wall) 치수는 유지. (박공은 split 공용 함수를 안 거치므로 여기서 직접 처리)
roof.set({ stroke: 'transparent' })
removeRoofLengthText(roof, canvas)
canvas
.getObjects()
.filter((obj) => obj.name === 'check')
@ -1722,6 +1723,16 @@ export const drawShedRoof = (roofId, canvas, textMode) => {
const maxLine = pitchSizeLines.reduce((prev, current) => (prev.length > current.length ? prev : current), pitchSizeLines[0])
canvas.add(maxLine)
// [docs §8] 한쪽흐름 외곽 처마선 — 내부 보조선이 없어 각 처마변이 통짜 innerLine 으로 그려진다.
// 경사변(gable)은 평면길이≠실제길이 라서 degreeOf 로 shedDegree 를 주입 → drawHipLine(plane/cos) 으로 보정.
// roof 원본 외곽(stroke) 숨김은 splitRoofLinesToInnerLines 가 담당.
roof.innerLines = roof.innerLines || []
splitRoofLinesToInnerLines(roof, roof.innerLines, canvas, textMode, {
degreeOf: (parentLine) => (parentLine.attributes?.type === LINE_TYPE.WALLLINE.GABLE ? shedDegree : 0),
})
// 지붕선 치수(roof lengthText) 제거는 split 내부 removeRoofLengthText 가 담당. 외벽선(wall) 치수는 유지.
canvas.renderAll()
}
@ -5445,6 +5456,18 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
canvas.renderAll()
}
/**
* 지붕선(roof.lines) 원본 길이 text(lengthText) 제거한다.
* 지붕선 치수는 위에 그려진 보조선(처마선 innerLine) 치수로 대체되므로 roof.lines 자체 치수는 숨긴다.
* 외벽선(wall) 치수는 유지한다. (변별/박공/용마루/한쪽흐름 공통)
*/
export const removeRoofLengthText = (roof, canvas) => {
canvas
?.getObjects()
.filter((o) => o.name === 'lengthText' && o.parentId === roof.id)
.forEach((o) => canvas.remove(o))
}
/**
* roof.lines(처마 외곽선) innerLine 끝점 기준으로 split 편집 가능한 innerLine(hip/roofLine)으로 만들고,
* 처마선 innerLine 외곽선을 전담하므로 roof 원본 외곽선(stroke) 숨긴다(transparent).
@ -5454,9 +5477,13 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
* @param {Array<QLine>} innerLines - 내부선 배열 (split 결과가 여기에 in-place 추가됨)
* @param {fabric.Canvas} canvas
* @param {string} textMode
* @param {{degreeOf?: (parentLine) => number}} [opts] - degreeOf: 부모 외곽변 경사각().
* 한쪽흐름 경사변(gable)처럼 평면길이실제길이인 변을 통짜로 그릴 drawHipLine 으로 실제길이 보정(plane/cos) docs §8.
* 미전달 기존 동작(분할점 인접 pitch 기반).
* @returns {Array<QLine>} innerLines
*/
export const splitRoofLinesToInnerLines = (roof, innerLines, canvas, textMode) => {
export const splitRoofLinesToInnerLines = (roof, innerLines, canvas, textMode, opts = {}) => {
const { degreeOf } = opts
// 분할점이 처마변 끝점(코너)과 이 거리(px) 이내면 분할에서 제외.
// SK 추녀 연장이 처마 코너에 닿을 때 ray cast 부동소수 오차(관측 0.02px)로 코너와 미세하게
// 어긋나면, 기존 almostEqual(1e-10)은 "끝점 아님"으로 오판 → 0 길이 조각 생성. END_EPS 로 흡수.
@ -5521,13 +5548,20 @@ export const splitRoofLinesToInnerLines = (roof, innerLines, canvas, textMode) =
innerLines.push(drawHipLine([startPoint.x, startPoint.y, currentLine.x2, currentLine.y2], canvas, roof, textMode, nextDegree, nextDegree))
}
} else {
innerLines.push(drawRoofLine([currentLine.x1, currentLine.y1, currentLine.x2, currentLine.y2], canvas, roof, textMode))
// 분할점 없는 통짜 변. degreeOf 가 주어지면(한쪽흐름) 경사변은 drawHipLine(plane/cos) 으로 실제길이 보정.
const deg = degreeOf ? degreeOf(currentLine) : 0
if (deg > 0) {
innerLines.push(drawHipLine([currentLine.x1, currentLine.y1, currentLine.x2, currentLine.y2], canvas, roof, textMode, deg, deg))
} else {
innerLines.push(drawRoofLine([currentLine.x1, currentLine.y1, currentLine.x2, currentLine.y2], canvas, roof, textMode))
}
}
})
// 처마선 innerLine 이 외곽선을 전담하므로 roof 원본 외곽(stroke)은 숨긴다.
// (안 숨기면 처마선 삭제 시 roof 의 기본 stroke:'black'(usePolygon.js) 이 노출됨)
// 처마선 innerLine 이 외곽선/치수를 전담하므로 roof 원본 외곽(stroke) 숨김 + 지붕선 치수(roof lengthText) 제거.
// (안 숨기면 처마선 삭제 시 roof 기본 stroke:'black'(usePolygon.js) 노출. 외벽선 wall 치수는 유지)
roof.set({ stroke: 'transparent' })
removeRoofLengthText(roof, canvas)
return innerLines
}