From f87bfb902e28cbb4dc43962144ec37c56f661bdb Mon Sep 17 00:00:00 2001 From: ysCha Date: Wed, 1 Apr 2026 15:14:14 +0900 Subject: [PATCH 1/4] =?UTF-8?q?[1423]=EC=84=A4=EA=B3=84=20=EA=B0=80?= =?UTF-8?q?=EC=A0=B8=EC=98=A4=EA=B8=B0=20=EA=B8=B0=EB=8A=A5=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/management/StuffDetail.jsx | 27 +++++++++++++++++++ .../management/popup/PlanRequestPop.jsx | 3 ++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index a3a0a607..12eef9ff 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -1046,6 +1046,33 @@ export default function StuffDetail() { form.setValue('otherSaleStoreId', info.saleStoreId) form.setValue('otherSaleStoreName', info.saleStoreName) form.setValue('otherSaleStoreLevel', info.saleStoreLevel) + get({ url: `/api/object/saleStore/${info.saleStoreId}/firstAgent` }).then((res) => { + if (res?.firstAgentId) { + const firstAgent = { saleStoreId: res.firstAgentId, saleStoreName: res.firstAgentName } + setSaleStoreList((prev) => { + const exists = prev.some((s) => s.saleStoreId === res.firstAgentId) + return exists ? prev : [...prev, firstAgent] + }) + setShowSaleStoreList((prev) => { + const exists = prev.some((s) => s.saleStoreId === res.firstAgentId) + return exists ? prev : [...prev, firstAgent] + }) + setSelOptions(res.firstAgentId) + form.setValue('saleStoreId', res.firstAgentId) + form.setValue('saleStoreName', res.firstAgentName) + form.setValue('saleStoreLevel', '1') + } else { + setSelOptions('') + form.setValue('saleStoreId', '') + form.setValue('saleStoreName', '') + form.setValue('saleStoreLevel', '') + } + }).catch(() => { + setSelOptions('') + form.setValue('saleStoreId', '') + form.setValue('saleStoreName', '') + form.setValue('saleStoreLevel', '') + }) } } diff --git a/src/components/management/popup/PlanRequestPop.jsx b/src/components/management/popup/PlanRequestPop.jsx index 2714a4e4..25df22f0 100644 --- a/src/components/management/popup/PlanRequestPop.jsx +++ b/src/components/management/popup/PlanRequestPop.jsx @@ -11,7 +11,7 @@ import { isObjectNotEmpty, queryStringFormatter } from '@/util/common-utils' import QPagination from '@/components/common/pagination/QPagination' import { useSwal } from '@/hooks/useSwal' import { QcastContext } from '@/app/QcastProvider' -import { sanitizeDecimalInputEvent } from '@/util/input-utils' +import { sanitizeDecimalInputEvent, sanitizeIntegerInputEvent } from '@/util/input-utils' export default function PlanRequestPop(props) { const [pageNo, setPageNo] = useState(1) //현재 페이지 번호 @@ -212,6 +212,7 @@ export default function PlanRequestPop(props) { //설계의뢰 그리드에서 선택한 설계의뢰 정보 const getSelectedRowdata = (data) => { if (isNotEmptyArray(data)) { + console.log('planReqObject fields:', data[0]) setPlanReqObject(data[0]) } else { setPlanReqObject({}) From 2101d30d98546fe8729b4118f6d07fe8ebb3d656 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 1 Apr 2026 17:11:58 +0900 Subject: [PATCH 2/4] =?UTF-8?q?1830=20=EB=AA=A8=EB=93=88=20=EC=84=A4?= =?UTF-8?q?=EC=B9=98=EC=98=81=EC=97=AD=20=EB=8C=80=EA=B0=81=20=EC=9E=88?= =?UTF-8?q?=EB=8A=94=20=ED=98=84=EC=83=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useMode.js | 48 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/src/hooks/useMode.js b/src/hooks/useMode.js index 8492042a..d014b25f 100644 --- a/src/hooks/useMode.js +++ b/src/hooks/useMode.js @@ -1756,6 +1756,11 @@ export function useMode() { offsetEdges.push(createOffsetEdge(edge, dx, dy)) }) + // 폴리곤의 감김 방향(signed area)을 구한다 + const signedArea = bevelJoin + ? polygon.edges.reduce((sum, edge) => sum + (edge.vertex1.x * edge.vertex2.y - edge.vertex2.x * edge.vertex1.y), 0) + : 0 + const vertices = [] offsetEdges.forEach((thisEdge, i) => { @@ -1765,9 +1770,22 @@ export function useMode() { if (!vertex.isIntersectionOutside || !bevelJoin) { vertices.push({ x: vertex.x, y: vertex.y }) } else { - // 둔각 + bevelJoin: offset edge 끝점 사용 - vertices.push({ x: prevEdge.vertex2.x, y: prevEdge.vertex2.y }) - vertices.push({ x: thisEdge.vertex1.x, y: thisEdge.vertex1.y }) + // 꼭짓점의 볼록/오목 판별 (cross product와 signed area 비교) + const origPrev = polygon.edges[(i + polygon.edges.length - 1) % polygon.edges.length] + const origThis = polygon.edges[i] + const cross = + (origPrev.vertex2.x - origPrev.vertex1.x) * (origThis.vertex2.y - origThis.vertex1.y) - + (origPrev.vertex2.y - origPrev.vertex1.y) * (origThis.vertex2.x - origThis.vertex1.x) + const isConvex = cross * signedArea > 0 + + if (isConvex) { + // 볼록 꼭짓점: bevel 적용 (offset edge 끝점 사용) + vertices.push({ x: prevEdge.vertex2.x, y: prevEdge.vertex2.y }) + vertices.push({ x: thisEdge.vertex1.x, y: thisEdge.vertex1.y }) + } else { + // 오목 꼭짓점: 교차점 사용 (90도 유지) + vertices.push({ x: vertex.x, y: vertex.y }) + } } } }) @@ -1795,6 +1813,11 @@ export function useMode() { offsetEdges.push(createOffsetEdge(edge, dx, dy)) }) + // 폴리곤의 감김 방향(signed area)을 구한다 + const signedArea = bevelJoin + ? polygon.edges.reduce((sum, edge) => sum + (edge.vertex1.x * edge.vertex2.y - edge.vertex2.x * edge.vertex1.y), 0) + : 0 + const vertices = [] offsetEdges.forEach((thisEdge, i) => { @@ -1804,9 +1827,22 @@ export function useMode() { if (!vertex.isIntersectionOutside || !bevelJoin) { vertices.push({ x: vertex.x, y: vertex.y }) } else { - // 둔각 + bevelJoin: offset edge 끝점 사용 - vertices.push({ x: prevEdge.vertex2.x, y: prevEdge.vertex2.y }) - vertices.push({ x: thisEdge.vertex1.x, y: thisEdge.vertex1.y }) + // 꼭짓점의 볼록/오목 판별 (cross product와 signed area 비교) + const origPrev = polygon.edges[(i + polygon.edges.length - 1) % polygon.edges.length] + const origThis = polygon.edges[i] + const cross = + (origPrev.vertex2.x - origPrev.vertex1.x) * (origThis.vertex2.y - origThis.vertex1.y) - + (origPrev.vertex2.y - origPrev.vertex1.y) * (origThis.vertex2.x - origThis.vertex1.x) + const isConvex = cross * signedArea > 0 + + if (isConvex) { + // 볼록 꼭짓점: bevel 적용 (offset edge 끝점 사용) + vertices.push({ x: prevEdge.vertex2.x, y: prevEdge.vertex2.y }) + vertices.push({ x: thisEdge.vertex1.x, y: thisEdge.vertex1.y }) + } else { + // 오목 꼭짓점: 교차점 사용 (90도 유지) + vertices.push({ x: vertex.x, y: vertex.y }) + } } } }) From 13f10fd18eb5e9464c9e6b578367b22b978742e3 Mon Sep 17 00:00:00 2001 From: ysCha Date: Wed, 1 Apr 2026 17:48:25 +0900 Subject: [PATCH 3/4] =?UTF-8?q?Revert=20"=EC=88=98=EB=8F=99=20=EB=B0=B0?= =?UTF-8?q?=EC=B9=98=20=EC=8B=9C=20=EC=9E=90=EB=8F=99=20=EB=AC=BC=EB=96=BC?= =?UTF-8?q?=EC=84=B8=20=EB=B0=B0=EC=B9=98=20=ED=95=9C=EB=8B=A4=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit b1c35376da012c1b685f7b58a0b14b3ffddf5425. --- src/components/floor-plan/modal/basic/BasicSetting.jsx | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index 04dbbcb0..983492bf 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -17,7 +17,6 @@ import { currentCanvasPlanState, isManualModuleLayoutSetupState, isManualModuleSetupState, - moduleSetupOptionState, toggleManualSetupModeState, } from '@/store/canvasAtom' import { loginUserStore } from '@/store/commonAtom' @@ -48,7 +47,6 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { const [checkedModules, setCheckedModules] = useRecoilState(checkedModuleState) const [roofs, setRoofs] = useState(addedRoofs) const [manualSetupMode, setManualSetupMode] = useRecoilState(toggleManualSetupModeState) - const [moduleSetupOption, setModuleSetupOption] = useRecoilState(moduleSetupOptionState) const [layoutSetup, setLayoutSetup] = useState([{}]) const { selectedModules, @@ -213,12 +211,8 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { } const handleManualModuleSetup = () => { - const nextManual = !isManualModuleSetup - setManualSetupMode(`manualSetup_${nextManual}`) - setIsManualModuleSetup(nextManual) - if (nextManual) { - setModuleSetupOption((prev) => ({ ...prev, isChidori: true })) - } + setManualSetupMode(`manualSetup_${!isManualModuleSetup}`) + setIsManualModuleSetup(!isManualModuleSetup) } const handleManualModuleLayoutSetup = () => { From 0e4b0b410f084cc39db72977fa9e0a0cf07281a3 Mon Sep 17 00:00:00 2001 From: ysCha Date: Wed, 1 Apr 2026 18:10:58 +0900 Subject: [PATCH 4/4] =?UTF-8?q?=ED=98=B9=EC=9E=A5=20=EA=B3=84=EC=82=B0=20r?= =?UTF-8?q?oofLine?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/util/skeleton-utils.js | 245 ++++++++++++++++++++++++++++++++----- 1 file changed, 212 insertions(+), 33 deletions(-) diff --git a/src/util/skeleton-utils.js b/src/util/skeleton-utils.js index 90601c15..17374edd 100644 --- a/src/util/skeleton-utils.js +++ b/src/util/skeleton-utils.js @@ -991,7 +991,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { newPStart.y = wallBaseLine.y1 findPoints.push({ x: ePoint.x, y: ePoint.y, position: 'left_in_start' }) - const newPointX = Big(roofLine.x1).plus(moveDist).abs().toNumber() + let newPointX = Big(roofLine.x1).plus(moveDist).abs().toNumber() const pDist = Big(wallLine.x1).minus(roofLine.x1).toNumber() const pLineY = Big(roofLine.y1).minus(0).abs().toNumber() // let idx = 0 > index - 1 ? sortRoofLines.length : index @@ -1005,8 +1005,14 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { // getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: newPointX, y: roofLine.y2 }, 'orange') if (Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) { - getAddLine({ x: pLineX, y: pLineY }, { x: newPointX, y: pLineY }, 'green') - getAddLine({ x: newPointX, y: pLineY }, { x: ePoint.x, y: ePoint.y }, 'pink') + // Validate: newPointX should not cross over pLineX (adjacent line) + if (newPointX > pLineX) { + console.warn('⚠️ [LEFT_IN_START] Line crossing detected! newPointX:', newPointX, 'exceeds pLineX:', pLineX, '| Clamping to prevent overlap') + newPointX = pLineX + } else { + getAddLine({ x: pLineX, y: pLineY }, { x: newPointX, y: pLineY }, 'green') + getAddLine({ x: newPointX, y: pLineY }, { x: ePoint.x, y: ePoint.y }, 'pink') + } } getAddLine(newPStart, newPEnd, 'red') @@ -1022,7 +1028,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { newPEnd.y = wallBaseLine.y2 findPoints.push({ x: ePoint.x, y: ePoint.y, position: 'left_in_end' }) - const newPointX = Big(roofLine.x1).plus(moveDist).toNumber() + let newPointX = Big(roofLine.x1).plus(moveDist).toNumber() const pDist = Big(wallLine.x1).minus(roofLine.x1).abs().toNumber() const pLineY = Big(roofLine.y2).minus(0).toNumber() // let idx = sortRoofLines.length < index + 1 ? 0 : index @@ -1036,14 +1042,84 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { // getAddLine({ x: roofLine.x1, y: roofLine.y1 }, { x: newPointX, y: roofLine.y1 }, 'orange') if (Math.abs(wallBaseLine.y2 - wallLine.y2) < 0.1) { - getAddLine({ x: pLineX, y: pLineY }, { x: newPointX, y: pLineY }, 'green') - getAddLine({ x: newPointX, y: pLineY }, { x: ePoint.x, y: ePoint.y }, 'pink') + // Validate: newPointX should not cross over pLineX (adjacent line) + if (newPointX > pLineX) { + console.warn('⚠️ [LEFT_IN_END] Line crossing detected! newPointX:', newPointX, 'exceeds pLineX:', pLineX, '| Clamping to prevent overlap') + newPointX = pLineX + } else { + getAddLine({ x: pLineX, y: pLineY }, { x: newPointX, y: pLineY }, 'green') + getAddLine({ x: newPointX, y: pLineY }, { x: ePoint.x, y: ePoint.y }, 'pink') + } } //getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: newPointX, y: roofLine.y2 }, 'orange') getAddLine(newPStart, newPEnd, 'red') } + + if(!isStartEnd.start && !isStartEnd.end){ + console.log('left_in::::isStartEnd:::::', isStartEnd) + const moveDistY1 = Big(roofLine.y1).minus(wallBaseLine.y1).abs().toNumber() + const moveDistX1 = Big(roofLine.x1).minus(wallBaseLine.x1).abs().toNumber() + const moveDistX2 = Big(roofLine.x2).minus(wallBaseLine.x2).abs().toNumber() + const moveDistY2 = Big(roofLine.y2).minus(wallBaseLine.y2).abs().toNumber() + + const sPoint = { x: wallBaseLine.x1, y: wallBaseLine.y1 } + const ePoint = { x: wallBaseLine.x2, y: wallBaseLine.y2 } + + + if(moveDistY1 > 0) { + findPoints.push({ x: sPoint.x, y: sPoint.y, position: 'left_in_start' }) + + if(moveDistY1 > moveDistX1){ + const dist = moveDistY1 - moveDistX1 + // console.log('Creating extensionLine (Y1 > X1):', { sPoint, roofLine, dist, roofId }) + const createdLine = getAddLine({ x: sPoint.x, y: sPoint.y }, { x: roofLine.x1, y: roofLine.y1 + dist }, 'orange','extensionLine') + console.log('extensionLine created - length:', createdLine.length, 'coords:', { x1: createdLine.x1, y1: createdLine.y1, x2: createdLine.x2, y2: createdLine.y2 }) + createdLine.set({ name: LINE_TYPE.SUBLINE.HIP, lineName: LINE_TYPE.SUBLINE.HIP, stroke: '#1083E3', strokeWidth: 2 }) + createdLine.attributes = { ...createdLine.attributes, type: LINE_TYPE.SUBLINE.HIP } + innerLines.push(createdLine) + + }else{ + const dist = moveDistX1 - moveDistY1 + // console.log('Creating extensionLine (X1 > Y1):', { sPoint, roofLine, dist, roofId }) + const createdLine = getAddLine({ x: sPoint.x, y: sPoint.y }, { x: roofLine.x1 + dist, y: roofLine.y1 }, 'orange','extensionLine') + console.log('extensionLine created - length:', createdLine.length, 'coords:', { x1: createdLine.x1, y1: createdLine.y1, x2: createdLine.x2, y2: createdLine.y2 }) + createdLine.set({ name: LINE_TYPE.SUBLINE.HIP, lineName: LINE_TYPE.SUBLINE.HIP, stroke: '#1083E3', strokeWidth: 2 }) + createdLine.attributes = { ...createdLine.attributes, type: LINE_TYPE.SUBLINE.HIP } + innerLines.push(createdLine) + } + + } + if(moveDistY2 > 0) { + findPoints.push({ x: ePoint.x, y: ePoint.y, position: 'left_in_end' }) + + if(moveDistY2 > moveDistX2){ + const dist = moveDistY2 - moveDistX2 + // getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: roofLine.x2, y: roofLine.y2 - dist }, 'red') + // console.log('Creating extensionLine (Y2 > X2):', { ePoint, roofLine, dist, roofId }) + const createdLine = getAddLine({ x: ePoint.x, y: ePoint.y }, { x: roofLine.x2, y: roofLine.y2 - dist }, 'orange', 'extensionLine') + console.log('extensionLine created1 - length:', createdLine.length, 'coords:', { x1: createdLine.x1, y1: createdLine.y1, x2: createdLine.x2, y2: createdLine.y2 }) + createdLine.set({ name: LINE_TYPE.SUBLINE.HIP, lineName: LINE_TYPE.SUBLINE.HIP, stroke: '#1083E3', strokeWidth: 2 }) + createdLine.attributes = { ...createdLine.attributes, type: LINE_TYPE.SUBLINE.HIP } + innerLines.push(createdLine) + + }else{ + const dist = moveDistX2 - moveDistY2 + // getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: roofLine.x2 - dist, y: roofLine.y2 }, 'red') + // console.log('Creating extensionLine (X2 > Y2):', { ePoint, roofLine, dist, roofId }) + const createdLine = getAddLine({ x: ePoint.x, y: ePoint.y }, { x: roofLine.x2 + dist, y: roofLine.y2 }, 'orange', 'extensionLine') + console.log('extensionLine created2 - length:', createdLine.length, 'coords:', { x1: createdLine.x1, y1: createdLine.y1, x2: createdLine.x2, y2: createdLine.y2 }) + createdLine.set({ name: LINE_TYPE.SUBLINE.HIP, lineName: LINE_TYPE.SUBLINE.HIP, stroke: '#1083E3', strokeWidth: 2 }) + createdLine.attributes = { ...createdLine.attributes, type: LINE_TYPE.SUBLINE.HIP } + innerLines.push(createdLine) + + } + } + + } + } else if (condition === 'left_out') { console.log('left_out::::isStartEnd:::::', isStartEnd) + if (isStartEnd.start) { const moveDist = Big(wallLine.x1).minus(wallBaseLine.x1).abs().toNumber() const aStartY = Big(roofLine.y1).minus(moveDist).abs().toNumber() @@ -1103,7 +1179,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { } if (isStartEnd.end) { - console.log('left_in::::isStartEnd:::::', isStartEnd) + console.log('left_out::::isStartEnd:::::', isStartEnd) const moveDist = Big(wallLine.x1).minus(wallBaseLine.x1).abs().toNumber() const aStartY = Big(roofLine.y2).plus(moveDist).toNumber() const bStartY = Big(wallLine.y2).plus(moveDist).toNumber() @@ -1163,7 +1239,9 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { findPoints.push({ y: newPStart.y, x: newPEnd.x, position: 'left_out_end' }) getAddLine(newPStart, newPEnd, 'red') } + } else if (condition === 'right_in') { + if (isStartEnd.start) { console.log('right_in::::isStartEnd:::::', isStartEnd) newPEnd.y = roofLine.y2 @@ -1174,7 +1252,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { newPStart.y = wallBaseLine.y1 findPoints.push({ x: ePoint.x, y: ePoint.y, position: 'right_in_start' }) - const newPointX = Big(roofLine.x1).minus(moveDist).abs().toNumber() + let newPointX = Big(roofLine.x1).minus(moveDist).abs().toNumber() const pDist = Big(wallLine.x1).minus(roofLine.x1).abs().toNumber() const pLineY = Big(roofLine.y1).minus(0).abs().toNumber() // let idx = 0 >= index - 1 ? sortRoofLines.length : index @@ -1188,8 +1266,14 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { //getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: newPointX, y: roofLine.y2 }, 'orange') if (Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) { - getAddLine({ x: pLineX, y: pLineY }, { x: newPointX, y: pLineY }, 'green') - getAddLine({ x: newPointX, y: pLineY }, { x: ePoint.x, y: ePoint.y }, 'pink') + // Validate: newPointX should not cross over pLineX (adjacent line) + if (newPointX < pLineX) { + console.warn('⚠️ [RIGHT_IN_START] Line crossing detected! newPointX:', newPointX, 'is less than pLineX:', pLineX, '| Clamping to prevent overlap') + newPointX = pLineX + } else { + getAddLine({ x: pLineX, y: pLineY }, { x: newPointX, y: pLineY }, 'green') + getAddLine({ x: newPointX, y: pLineY }, { x: ePoint.x, y: ePoint.y }, 'pink') + } } getAddLine(newPStart, newPEnd, 'red') } @@ -1204,7 +1288,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { newPEnd.y = wallBaseLine.y2 findPoints.push({ x: ePoint.x, y: ePoint.y, position: 'right_in_end' }) - const newPointX = Big(roofLine.x1).minus(moveDist).toNumber() + let newPointX = Big(roofLine.x1).minus(moveDist).toNumber() const pDist = Big(wallLine.x1).minus(roofLine.x1).abs().toNumber() const pLineY = Big(roofLine.y2).minus(0).abs().toNumber() // let idx = sortRoofLines.length < index + 1 ? 0 : index @@ -1218,12 +1302,82 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { //getAddLine({ x: roofLine.x1, y: Big(roofLine.y1).minus(moveDist).toNumber() }, { x: newPointX, y: Big(roofLine.y1).minus(moveDist).toNumber()}, 'orange') if (Math.abs(wallBaseLine.y2 - wallLine.y2) < 0.1) { - getAddLine({ x: pLineX, y: pLineY }, { x: newPointX, y: pLineY }, 'green') - getAddLine({ x: newPointX, y: pLineY }, { x: ePoint.x, y: ePoint.y }, 'pink') + // Validate: newPointX should not cross over pLineX (adjacent line) + if (newPointX < pLineX) { + console.warn('⚠️ [RIGHT_IN_END] Line crossing detected! newPointX:', newPointX, 'is less than pLineX:', pLineX, '| Clamping to prevent overlap') + newPointX = pLineX + } else { + getAddLine({ x: pLineX, y: pLineY }, { x: newPointX, y: pLineY }, 'green') + getAddLine({ x: newPointX, y: pLineY }, { x: ePoint.x, y: ePoint.y }, 'pink') + } } //getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: newPointX, y: roofLine.y2 }, 'orange') getAddLine(newPStart, newPEnd, 'red') } + + if(!isStartEnd.start && !isStartEnd.end){ + console.log('right_in::::isStartEnd:::::', isStartEnd) + const moveDistY1 = Big(roofLine.y1).minus(wallBaseLine.y1).abs().toNumber() + const moveDistX1 = Big(roofLine.x1).minus(wallBaseLine.x1).abs().toNumber() + const moveDistX2 = Big(roofLine.x2).minus(wallBaseLine.x2).abs().toNumber() + const moveDistY2 = Big(roofLine.y2).minus(wallBaseLine.y2).abs().toNumber() + + const sPoint = { x: wallBaseLine.x1, y: wallBaseLine.y1 } + const ePoint = { x: wallBaseLine.x2, y: wallBaseLine.y2 } + + + if(moveDistY1 > 0) { + findPoints.push({ x: sPoint.x, y: sPoint.y, position: 'right_in_start' }) + + if(moveDistY1 > moveDistX1){ + const dist = moveDistY1 - moveDistX1 + // console.log('Creating extensionLine (Y1 > X1):', { sPoint, roofLine, dist, roofId }) + const createdLine = getAddLine({ x: sPoint.x, y: sPoint.y }, { x: roofLine.x1, y: roofLine.y1 + dist }, 'orange','extensionLine') + console.log('extensionLine created - length:', createdLine.length, 'coords:', { x1: createdLine.x1, y1: createdLine.y1, x2: createdLine.x2, y2: createdLine.y2 }) + createdLine.set({ name: LINE_TYPE.SUBLINE.HIP, lineName: LINE_TYPE.SUBLINE.HIP, stroke: '#1083E3', strokeWidth: 2 }) + createdLine.attributes = { ...createdLine.attributes, type: LINE_TYPE.SUBLINE.HIP } + innerLines.push(createdLine) + + }else{ + const dist = moveDistX1 - moveDistY1 + // console.log('Creating extensionLine (X1 > Y1):', { sPoint, roofLine, dist, roofId }) + const createdLine = getAddLine({ x: sPoint.x, y: sPoint.y }, { x: roofLine.x1 - dist, y: roofLine.y1 }, 'orange','extensionLine') + console.log('extensionLine created - length:', createdLine.length, 'coords:', { x1: createdLine.x1, y1: createdLine.y1, x2: createdLine.x2, y2: createdLine.y2 }) + createdLine.set({ name: LINE_TYPE.SUBLINE.HIP, lineName: LINE_TYPE.SUBLINE.HIP, stroke: '#1083E3', strokeWidth: 2 }) + createdLine.attributes = { ...createdLine.attributes, type: LINE_TYPE.SUBLINE.HIP } + innerLines.push(createdLine) + } + + } + if(moveDistY2 > 0) { + findPoints.push({ x: ePoint.x, y: ePoint.y, position: 'right_in_end' }) + + if(moveDistY2 > moveDistX2){ + const dist = moveDistY2 - moveDistX2 + // getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: roofLine.x2, y: roofLine.y2 - dist }, 'red') + // console.log('Creating extensionLine (Y2 > X2):', { ePoint, roofLine, dist, roofId }) + const createdLine = getAddLine({ x: ePoint.x, y: ePoint.y }, { x: roofLine.x2, y: roofLine.y2 - dist }, 'orange', 'extensionLine') + console.log('extensionLine created1 - length:', createdLine.length, 'coords:', { x1: createdLine.x1, y1: createdLine.y1, x2: createdLine.x2, y2: createdLine.y2 }) + createdLine.set({ name: LINE_TYPE.SUBLINE.HIP, lineName: LINE_TYPE.SUBLINE.HIP, stroke: '#1083E3', strokeWidth: 2 }) + createdLine.attributes = { ...createdLine.attributes, type: LINE_TYPE.SUBLINE.HIP } + innerLines.push(createdLine) + + }else{ + const dist = moveDistX2 - moveDistY2 + // getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: roofLine.x2 - dist, y: roofLine.y2 }, 'red') + // console.log('Creating extensionLine (X2 > Y2):', { ePoint, roofLine, dist, roofId }) + const createdLine = getAddLine({ x: ePoint.x, y: ePoint.y }, { x: roofLine.x2 - dist, y: roofLine.y2 }, 'orange', 'extensionLine') + console.log('extensionLine created2 - length:', createdLine.length, 'coords:', { x1: createdLine.x1, y1: createdLine.y1, x2: createdLine.x2, y2: createdLine.y2 }) + createdLine.set({ name: LINE_TYPE.SUBLINE.HIP, lineName: LINE_TYPE.SUBLINE.HIP, stroke: '#1083E3', strokeWidth: 2 }) + createdLine.attributes = { ...createdLine.attributes, type: LINE_TYPE.SUBLINE.HIP } + innerLines.push(createdLine) + + } + } + + } + + } else if (condition === 'right_out') { console.log('right_out::::isStartEnd:::::', isStartEnd) if (isStartEnd.start) { @@ -1370,7 +1524,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { sPoint = { x: wallBaseLine.x1, y: wallBaseLine.y1 } newPStart.x = wallBaseLine.x1 - const newPointY = Big(roofLine.y2).plus(moveDist).toNumber() + let newPointY = Big(roofLine.y2).plus(moveDist).toNumber() const pDist = Big(wallLine.y2).minus(roofLine.y2).abs().toNumber() const pLineX = Big(roofLine.x1).minus(0).toNumber() @@ -1386,8 +1540,14 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { findPoints.push({ x: sPoint.x, y: sPoint.y, position: 'top_in_start' }) if (Math.abs(wallBaseLine.x1 - wallLine.x1) < 0.1) { - getAddLine({ x: pLineX, y: pLineY }, { x: pLineX, y: newPointY }, 'green') - getAddLine({ x: pLineX, y: newPointY }, { x: sPoint.x, y: sPoint.y }, 'pink') + // Validate: newPointY should not cross over pLineY (adjacent line) + if (newPointY > pLineY) { + console.warn('⚠️ [TOP_IN_START] Line crossing detected! newPointY:', newPointY, 'exceeds pLineY:', pLineY, '| Clamping to prevent overlap') + newPointY = pLineY + } else { + getAddLine({ x: pLineX, y: pLineY }, { x: pLineX, y: newPointY }, 'green') + getAddLine({ x: pLineX, y: newPointY }, { x: sPoint.x, y: sPoint.y }, 'pink') + } } //getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: roofLine.x2, y: newPointY }, 'orange') getAddLine(newPStart, newPEnd, 'red') @@ -1399,7 +1559,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { sPoint = { x: wallBaseLine.x2, y: wallBaseLine.y2 } newPEnd.x = wallBaseLine.x2 - const newPointY = Big(roofLine.y1).plus(moveDist).toNumber() + let newPointY = Big(roofLine.y1).plus(moveDist).toNumber() const pDist = Big(wallLine.y1).minus(roofLine.y1).abs().toNumber() const pLineX = Big(roofLine.x2).minus(0).toNumber() @@ -1415,20 +1575,27 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { findPoints.push({ x: sPoint.x, y: sPoint.y, position: 'top_in_end' }) if (Math.abs(wallBaseLine.x2 - wallLine.x2) < 0.1) { - getAddLine({ x: pLineX, y: pLineY }, { x: pLineX, y: newPointY }, 'green') - getAddLine({ x: pLineX, y: newPointY }, { x: sPoint.x, y: sPoint.y }, 'pink') + // Validate: newPointY should not cross over pLineY (adjacent line) + if (newPointY > pLineY) { + console.warn('⚠️ [TOP_IN_END] Line crossing detected! newPointY:', newPointY, 'exceeds pLineY:', pLineY, '| Clamping to prevent overlap') + newPointY = pLineY + } else { + getAddLine({ x: pLineX, y: pLineY }, { x: pLineX, y: newPointY }, 'green') + getAddLine({ x: pLineX, y: newPointY }, { x: sPoint.x, y: sPoint.y }, 'pink') + } } //getAddLine({ x: roofLine.x1, y: roofLine.y1 }, { x: roofLine.x1, y: newPointY }, 'orange') getAddLine(newPStart, newPEnd, 'red') } + if(!isStartEnd.start && !isStartEnd.end){ console.log('top_in start and end false') - const moveDistY1 = Big(wallLine.y1).minus(wallBaseLine.y1).abs().toNumber() - const moveDistX1 = Big(wallLine.x1).minus(wallBaseLine.x1).abs().toNumber() - const moveDistX2 = Big(wallLine.x2).minus(wallBaseLine.x2).abs().toNumber() - const moveDistY2 = Big(wallLine.y2).minus(wallBaseLine.y2).abs().toNumber() + const moveDistY1 = Big(roofLine.y1).minus(wallBaseLine.y1).abs().toNumber() + const moveDistX1 = Big(roofLine.x1).minus(wallBaseLine.x1).abs().toNumber() + const moveDistX2 = Big(roofLine.x2).minus(wallBaseLine.x2).abs().toNumber() + const moveDistY2 = Big(roofLine.y2).minus(wallBaseLine.y2).abs().toNumber() const sPoint = { x: wallBaseLine.x1, y: wallBaseLine.y1 } const ePoint = { x: wallBaseLine.x2, y: wallBaseLine.y2 } @@ -1609,7 +1776,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { sPoint = { x: wallBaseLine.x1, y: wallBaseLine.y1 } newPStart.x = wallBaseLine.x1 - const newPointY = Big(roofLine.y2).minus(moveDist).toNumber() + let newPointY = Big(roofLine.y2).minus(moveDist).toNumber() const pDist = Big(wallLine.y2).minus(roofLine.y2).abs().toNumber() const pLineX = Big(roofLine.x1).minus(0).toNumber() @@ -1625,8 +1792,14 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { findPoints.push({ x: sPoint.x, y: sPoint.y, position: 'bottom_in_start' }) if (Math.abs(wallBaseLine.x1 - wallLine.x1) < 0.1) { - getAddLine({ x: pLineX, y: pLineY }, { x: pLineX, y: newPointY }, 'green') - getAddLine({ x: pLineX, y: newPointY }, { x: sPoint.x, y: sPoint.y }, 'pink') + // Validate: newPointY should not cross over pLineY (adjacent line) + if (newPointY < pLineY) { + console.warn('⚠️ [BOTTOM_IN_START] Line crossing detected! newPointY:', newPointY, 'is less than pLineY:', pLineY, '| Clamping to prevent overlap') + newPointY = pLineY + } else { + getAddLine({ x: pLineX, y: pLineY }, { x: pLineX, y: newPointY }, 'green') + getAddLine({ x: pLineX, y: newPointY }, { x: sPoint.x, y: sPoint.y }, 'pink') + } } //getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: roofLine.x2, y: newPointY }, 'orange') getAddLine(newPStart, newPEnd, 'red') @@ -1638,7 +1811,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { sPoint = { x: wallBaseLine.x2, y: wallBaseLine.y2 } newPEnd.x = wallBaseLine.x2 - const newPointY = Big(roofLine.y1).minus(moveDist).toNumber() + let newPointY = Big(roofLine.y1).minus(moveDist).toNumber() const pDist = Big(wallLine.y1).minus(roofLine.y1).abs().toNumber() const pLineX = Big(roofLine.x2).minus(0).toNumber() @@ -1655,8 +1828,14 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { findPoints.push({ x: sPoint.x, y: sPoint.y, position: 'bottom_in_end' }) if (Math.abs(wallBaseLine.x2 - wallLine.x2) < 0.1) { - getAddLine({ x: pLineX, y: pLineY }, { x: pLineX, y: newPointY }, 'green') - getAddLine({ x: pLineX, y: newPointY }, { x: sPoint.x, y: sPoint.y }, 'pink') + // Validate: newPointY should not cross over pLineY (adjacent line) + if (newPointY < pLineY) { + console.warn('⚠️ [BOTTOM_IN_END] Line crossing detected! newPointY:', newPointY, 'is less than pLineY:', pLineY, '| Clamping to prevent overlap') + newPointY = pLineY + }else { + getAddLine({ x: pLineX, y: pLineY }, { x: pLineX, y: newPointY }, 'green') + getAddLine({ x: pLineX, y: newPointY }, { x: sPoint.x, y: sPoint.y }, 'pink') + } } //getAddLine({ x: roofLine.x1, y: roofLine.y1 }, { x: roofLine.x1, y: newPointY }, 'orange') getAddLine(newPStart, newPEnd, 'red') @@ -1666,10 +1845,10 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { console.log('isStartEnd:::::', isStartEnd) - const moveDistY1 = Big(wallLine.y1).minus(wallBaseLine.y1).abs().toNumber() - const moveDistX1 = Big(wallLine.x1).minus(wallBaseLine.x1).abs().toNumber() - const moveDistX2 = Big(wallLine.x2).minus(wallBaseLine.x2).abs().toNumber() - const moveDistY2 = Big(wallLine.y2).minus(wallBaseLine.y2).abs().toNumber() + const moveDistY1 = Big(roofLine.y1).minus(wallBaseLine.y1).abs().toNumber() + const moveDistX1 = Big(roofLine.x1).minus(wallBaseLine.x1).abs().toNumber() + const moveDistX2 = Big(roofLine.x2).minus(wallBaseLine.x2).abs().toNumber() + const moveDistY2 = Big(roofLine.y2).minus(wallBaseLine.y2).abs().toNumber() const sPoint = { x: wallBaseLine.x1, y: wallBaseLine.y1 } const ePoint = { x: wallBaseLine.x2, y: wallBaseLine.y2 }