[2243] 配置面 입력치수 라벨 변질 수정 — planeSize 2순위/2단계 ±20mm 흡착 제거, 끝점 공유변만 상속 #893

Merged
ysCha merged 1 commits from hotfix/dev_yscha into dev 2026-06-08 15:31:51 +09:00

View File

@ -305,25 +305,25 @@ export function usePlacementShapeDrawing(id) {
} }
}, [points]) }, [points])
// 기존 도형의 변과 일치하는 경우 planeSize를 상속하는 함수 // 기존 도형의 변과 일치하는 경우 planeSize를 상속하는 함수.
// [2026-06-08] 흡착으로 끝점을 정확히 공유한 변(1순위)만 상속.
// 기존 2순위(끝점 비공유 평행+유사길이)/2단계 전파는 ±20mm(tolerance 2좌표=20mm) 흡착창으로
// 인접하지 않은 별개 屋根까지 끌어와 사용자가 입력한 치수를 변질시켜 제거. tolerance 도 5mm 로 축소.
const inheritPlaneSizeFromExistingShapes = (newPolygon) => { const inheritPlaneSizeFromExistingShapes = (newPolygon) => {
const tolerance = 2 const tolerance = 0.5
const existingPolygons = canvas.getObjects().filter( const existingPolygons = canvas.getObjects().filter(
(obj) => (obj.name === POLYGON_TYPE.ROOF || obj.name === POLYGON_TYPE.WALL) && obj.id !== newPolygon.id && obj.lines, (obj) => (obj.name === POLYGON_TYPE.ROOF || obj.name === POLYGON_TYPE.WALL) && obj.id !== newPolygon.id && obj.lines,
) )
if (existingPolygons.length === 0) return if (existingPolygons.length === 0) return
const inheritedSet = new Set() let inherited = false
// 1단계: 기존 도형의 변과 매칭하여 planeSize 상속 newPolygon.lines.forEach((line) => {
newPolygon.lines.forEach((line, lineIdx) => {
const x1 = line.x1, const x1 = line.x1,
y1 = line.y1, y1 = line.y1,
x2 = line.x2, x2 = line.x2,
y2 = line.y2 y2 = line.y2
const isHorizontal = Math.abs(y1 - y2) < tolerance
const isVertical = Math.abs(x1 - x2) < tolerance
for (const polygon of existingPolygons) { for (const polygon of existingPolygons) {
for (const edge of polygon.lines) { for (const edge of polygon.lines) {
@ -334,7 +334,7 @@ export function usePlacementShapeDrawing(id) {
ex2 = edge.x2, ex2 = edge.x2,
ey2 = edge.y2 ey2 = edge.y2
// 1순위: 양 끝점이 정확히 일치 // 양 끝점이 정확히 일치(흡착 공유변)할 때만 상속
const forwardMatch = const forwardMatch =
Math.abs(x1 - ex1) < tolerance && Math.abs(x1 - ex1) < tolerance &&
Math.abs(y1 - ey1) < tolerance && Math.abs(y1 - ey1) < tolerance &&
@ -351,91 +351,27 @@ export function usePlacementShapeDrawing(id) {
if (edge.attributes.actualSize) { if (edge.attributes.actualSize) {
line.attributes.actualSize = edge.attributes.actualSize line.attributes.actualSize = edge.attributes.actualSize
} }
inheritedSet.add(lineIdx) inherited = true
return
}
// 2순위: 같은 방향 + 같은 좌표 차이 (끝점 공유 불필요)
if (isHorizontal && Math.abs(ey1 - ey2) < tolerance && Math.abs(Math.abs(x2 - x1) - Math.abs(ex2 - ex1)) < tolerance) {
line.attributes = { ...line.attributes, planeSize: edge.attributes.planeSize }
if (edge.attributes.actualSize) {
line.attributes.actualSize = edge.attributes.actualSize
}
inheritedSet.add(lineIdx)
return
}
if (isVertical && Math.abs(ex1 - ex2) < tolerance && Math.abs(Math.abs(y2 - y1) - Math.abs(ey2 - ey1)) < tolerance) {
line.attributes = { ...line.attributes, planeSize: edge.attributes.planeSize }
if (edge.attributes.actualSize) {
line.attributes.actualSize = edge.attributes.actualSize
}
inheritedSet.add(lineIdx)
return return
} }
} }
} }
}) })
// 2단계: 상속받은 변과 평행하고 좌표 차이가 같은 변에 planeSize 전파
if (inheritedSet.size > 0) {
newPolygon.lines.forEach((line, lineIdx) => {
if (inheritedSet.has(lineIdx)) return
const x1 = line.x1,
y1 = line.y1,
x2 = line.x2,
y2 = line.y2
const isHorizontal = Math.abs(y1 - y2) < tolerance
const isVertical = Math.abs(x1 - x2) < tolerance
for (const idx of inheritedSet) {
const inherited = newPolygon.lines[idx]
const ix1 = inherited.x1,
iy1 = inherited.y1,
ix2 = inherited.x2,
iy2 = inherited.y2
const iIsHorizontal = Math.abs(iy1 - iy2) < tolerance
const iIsVertical = Math.abs(ix1 - ix2) < tolerance
if (isHorizontal && iIsHorizontal) {
if (Math.abs(Math.abs(x2 - x1) - Math.abs(ix2 - ix1)) < tolerance) {
line.attributes = { ...line.attributes, planeSize: inherited.attributes.planeSize }
if (inherited.attributes.actualSize) {
line.attributes.actualSize = inherited.attributes.actualSize
}
inheritedSet.add(lineIdx)
return
}
} else if (isVertical && iIsVertical) {
if (Math.abs(Math.abs(y2 - y1) - Math.abs(iy2 - iy1)) < tolerance) {
line.attributes = { ...line.attributes, planeSize: inherited.attributes.planeSize }
if (inherited.attributes.actualSize) {
line.attributes.actualSize = inherited.attributes.actualSize
}
inheritedSet.add(lineIdx)
return
}
}
}
})
}
// planeSize가 상속된 경우 길이 텍스트를 다시 렌더링 // planeSize가 상속된 경우 길이 텍스트를 다시 렌더링
if (inheritedSet.size > 0) { if (inherited) {
addLengthText(newPolygon) addLengthText(newPolygon)
} }
} }
// 기존 도형에서 매칭되는 변의 planeSize를 찾는 헬퍼 함수 // 기존 도형에서 매칭되는 변의 planeSize를 찾는 헬퍼 함수.
// [2026-06-08] 끝점이 정확히 일치하는 흡착 공유변만 상속.
const findMatchingEdgePlaneSize = (x1, y1, x2, y2) => { const findMatchingEdgePlaneSize = (x1, y1, x2, y2) => {
const tolerance = 2 const tolerance = 0.5
const existingPolygons = canvas.getObjects().filter( const existingPolygons = canvas.getObjects().filter(
(obj) => (obj.name === POLYGON_TYPE.ROOF || obj.name === POLYGON_TYPE.WALL) && obj.lines, (obj) => (obj.name === POLYGON_TYPE.ROOF || obj.name === POLYGON_TYPE.WALL) && obj.lines,
) )
const isHorizontal = Math.abs(y1 - y2) < tolerance
const isVertical = Math.abs(x1 - x2) < tolerance
for (const polygon of existingPolygons) { for (const polygon of existingPolygons) {
for (const edge of polygon.lines) { for (const edge of polygon.lines) {
if (!edge.attributes?.planeSize) continue if (!edge.attributes?.planeSize) continue
@ -444,7 +380,7 @@ export function usePlacementShapeDrawing(id) {
ex2 = edge.x2, ex2 = edge.x2,
ey2 = edge.y2 ey2 = edge.y2
// 1순위: 양 끝점 일치 (정방향/역방향) // 양 끝점 일치 (정방향/역방향)
const forwardMatch = const forwardMatch =
Math.abs(x1 - ex1) < tolerance && Math.abs(y1 - ey1) < tolerance && Math.abs(x2 - ex2) < tolerance && Math.abs(y2 - ey2) < tolerance Math.abs(x1 - ex1) < tolerance && Math.abs(y1 - ey1) < tolerance && Math.abs(x2 - ex2) < tolerance && Math.abs(y2 - ey2) < tolerance
const reverseMatch = const reverseMatch =
@ -453,14 +389,6 @@ export function usePlacementShapeDrawing(id) {
if (forwardMatch || reverseMatch) { if (forwardMatch || reverseMatch) {
return edge.attributes.planeSize return edge.attributes.planeSize
} }
// 2순위: 같은 방향 + 같은 좌표 차이 (끝점 공유 불필요)
if (isHorizontal && Math.abs(ey1 - ey2) < tolerance && Math.abs(Math.abs(x2 - x1) - Math.abs(ex2 - ex1)) < tolerance) {
return edge.attributes.planeSize
}
if (isVertical && Math.abs(ex1 - ex2) < tolerance && Math.abs(Math.abs(y2 - y1) - Math.abs(ey2 - ey1)) < tolerance) {
return edge.attributes.planeSize
}
} }
} }
return null return null