From fc6bf3a01d2908169a07c3d0742476367784af83 Mon Sep 17 00:00:00 2001 From: ysCha Date: Thu, 27 Nov 2025 18:47:49 +0900 Subject: [PATCH] =?UTF-8?q?=ED=99=95=EC=9E=A52?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../roofcover/useRoofAllocationSetting.js | 4 +- src/util/skeleton-utils.js | 255 ++++++++++++++++-- 2 files changed, 241 insertions(+), 18 deletions(-) diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js index 8a330c4d..ee89e443 100644 --- a/src/hooks/roofcover/useRoofAllocationSetting.js +++ b/src/hooks/roofcover/useRoofAllocationSetting.js @@ -408,7 +408,7 @@ export function useRoofAllocationSetting(id) { try { const roofEaveHelpLines = canvas.getObjects().filter(obj => - obj.name === 'eaveHelpLine' && obj.roofId === roofBase.id + obj.lineName === 'eaveHelpLine' && obj.roofId === roofBase.id ); @@ -416,7 +416,7 @@ export function useRoofAllocationSetting(id) { // Filter out any eaveHelpLines that are already in lines to avoid duplicates const existingEaveLineIds = new Set(roofBase.lines.map(line => line.id)); const newEaveLines = roofEaveHelpLines.filter(line => !existingEaveLineIds.has(line.id)); - roofBase.lines = [...roofBase.lines, ...newEaveLines]; + roofBase.lines = [...newEaveLines]; } else { roofBase.lines = [...roofEaveHelpLines]; } diff --git a/src/util/skeleton-utils.js b/src/util/skeleton-utils.js index bf48b203..f8c91eea 100644 --- a/src/util/skeleton-utils.js +++ b/src/util/skeleton-utils.js @@ -604,7 +604,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { isBaseLine: sktLine.attributes.isOuterEdge, lineName: (sktLine.attributes.isOuterEdge)?'roofLine': attributes.type, selectable:(!sktLine.attributes.isOuterEdge), - visible: (!sktLine.attributes.isOuterEdge), + //visible: (!sktLine.attributes.isOuterEdge), }); coordinateText(skeletonLine) @@ -772,6 +772,9 @@ if(roof.moveUpDown??0 > 0) { const moveLine = sortedWallBaseLines[index] const wallBaseLine = sortedWallBaseLines[index] + //roofline 외곽선 설정 + + console.log('=== Line Coordinates ==='); console.table({ 'Point' : ['X', 'Y'], @@ -793,6 +796,7 @@ if(roof.moveUpDown??0 > 0) { if (!origin) return if (isSamePoint(moveLine, wallLine)) { + return false } @@ -826,7 +830,8 @@ if(roof.moveUpDown??0 > 0) { visible : true, roofId : roofId, attributes : { - type: 'eaveHelpLine' + type: 'eaveHelpLine', + isStart : true } }); coordinateText(line) @@ -835,12 +840,51 @@ if(roof.moveUpDown??0 > 0) { return line } + getAddLine(roofLine.startPoint, roofLine.endPoint) + newPStart = { x: roofLine.x1, y: roofLine.y1 } + newPEnd = { x: roofLine.x2, y: roofLine.y2 } + + // Usage in your code: + // if (fullyMoved) { + // const result = adjustLinePoints({ + // roofLine, + // currentRoofLine, + // wallBaseLine, + // origin, + // moveType: 'both' // Adjust both start and end points + // }); + // newPStart = result.newPStart; + // newPEnd = result.newPEnd; + // getAddLine(newPStart, newPEnd, 'red'); + // } + // else if (movedStart) { + // const result = adjustLinePoints({ + // roofLine, + // currentRoofLine, + // wallBaseLine, + // origin, + // moveType: 'start' // Only adjust start point + // }); + // newPStart = result.newPStart; + // getAddLine(newPStart, newPEnd, 'green'); + // } + // else if (movedEnd) { + // const result = adjustLinePoints({ + // roofLine, + // currentRoofLine, + // wallBaseLine, + // origin, + // moveType: 'end' // Only adjust end point + // }); + // newPEnd = result.newPEnd; + // getAddLine(newPStart, newPEnd, 'orange'); + // } + // canvas.renderAll() //두 포인트가 변경된 라인인 if (fullyMoved) { //반시계방향향 - newPStart = { x: roofLine.x1, y: roofLine.y1 } - newPEnd = { x: roofLine.x2, y: roofLine.y2 } + console.log("moveFully:::::::::::::", wallBaseLine, newPStart, newPEnd) @@ -914,7 +958,6 @@ if(roof.moveUpDown??0 > 0) { } else if (movedStart) { //end 변경경 - newPStart = { x: roofLine.x1, y: roofLine.y1 } if (getOrientation(roofLine) === 'vertical') { @@ -923,8 +966,36 @@ if(roof.moveUpDown??0 > 0) { isCross = true; } - //newPStart = { x: roofLine.x2, y: roofLine.y2 } - newPEnd = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y1 : origin.y1 } + if(newPStart.y <= wallBaseLine.y1 && wallBaseLine.y1 < wallBaseLine.y2 && wallBaseLine.y2 < newPEnd.y){//가장 왼쪽v + newPStart = { x: roofLine.x1, y: roofLine.y1 } + newPEnd = { x: roofLine.x2, y: (isCross) ? currentRoofLine.y1 : wallBaseLine.y1 } + + }else if(newPEnd.y <= wallBaseLine.y2 && wallBaseLine.y2 < wallBaseLine.y1 && wallBaseLine.y1 <= newPStart.y){ //하단 오른쪽v + newPStart = { x: roofLine.x1, y: roofLine.y1 } + newPEnd = { x: roofLine.x2, y: (isCross) ? currentRoofLine.y1 : wallBaseLine.y1 } + + }else if(newPEnd.y <= wallBaseLine.y2 && wallBaseLine.y2 <= newPStart.y && newPStart.y <= wallBaseLine.y1) { //상단 왼쪽v + + newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y1 : wallBaseLine.y1 } + newPEnd ={ x: roofLine.x2, y: roofLine.y2 } + + }else if(newPStart.y <= wallBaseLine.y1 && wallBaseLine.y1 <= newPEnd.y && newPEnd.y <= wallBaseLine.y2) {//상단 오르쪽 + + newPStart = { x: roofLine.x1, y: roofLine.y1 } + newPEnd = { x: roofLine.x2, y: (isCross) ? currentRoofLine.y1 : wallBaseLine.y1 } + + }else if(wallBaseLine.y1 <= newPStart.y && newPStart.y <= wallBaseLine.y2 && wallBaseLine.y2 <= newPEnd.y) { //하단 오른쪽v + + newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y1 : wallBaseLine.y1 } + newPEnd = { x: roofLine.x2, y: roofLine.y2 } + + }else if (wallBaseLine.y2 <= newPEnd.y && newPEnd.y <= wallBaseLine.y1 && wallBaseLine.y1 <= newPStart.y) { //하단 왼쪽 + + newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y1 : wallBaseLine.y1 } + newPEnd ={ x: roofLine.x2, y: roofLine.y2 } + } + + } else if (getOrientation(roofLine) === 'horizontal') { @@ -932,20 +1003,46 @@ if(roof.moveUpDown??0 > 0) { if (Math.abs(currentRoofLine.y1 - roofLine.y2) < 0.1 || Math.abs(currentRoofLine.y2 - roofLine.y1) < 0.1) { isCross = true; } + if(newPStart.x <= wallBaseLine.x1 && wallBaseLine.x1 < wallBaseLine.x2 && wallBaseLine.x2 < newPEnd.x){//가장 왼쪽v + newPStart = { y: roofLine.y1, x: roofLine.x1 } + newPEnd = { y: roofLine.y2, x: (isCross) ? currentRoofLine.x1 : wallBaseLine.x1 } - newPEnd = { x: (isCross) ? currentRoofLine.x1 : origin.x1, y: roofLine.y1 } //수직라인 접점까지지 + }else if(newPEnd.x <= wallBaseLine.x2 && wallBaseLine.x2 < wallBaseLine.x1 && wallBaseLine.x1 <= newPStart.x){ //하단 오른쪽v + newPStart = { y: roofLine.y1, x: roofLine.x1 } + newPEnd = { y: roofLine.y2, x: (isCross) ? currentRoofLine.x1 : wallBaseLine.x1 } + }else if(newPEnd.x <= wallBaseLine.x2 && wallBaseLine.x2 <= newPStart.x && newPStart.x <= wallBaseLine.x1) { //상단 왼쪽v + + newPStart = { y: roofLine.y1, x: (isCross) ? currentRoofLine.x1 : wallBaseLine.x1 } + newPEnd ={ y: roofLine.y2, x: roofLine.x2 } + + }else if(newPStart.x <= wallBaseLine.x1 && wallBaseLine.x1 <= newPEnd.x && newPEnd.x <= wallBaseLine.x2) {//상단 오르쪽 + + newPStart = { y: roofLine.y1, x: (isCross) ? currentRoofLine.x1 : wallBaseLine.x1 } + newPEnd ={ y: roofLine.y2, x: roofLine.x2 } + + }else if(wallBaseLine.x1 <= newPStart.x && newPStart.x <= wallBaseLine.x2 && wallBaseLine.x2 <= newPEnd.x) { //하단 오른쪽v + + newPStart = { y: roofLine.y1, x: (isCross) ? currentRoofLine.y1 : wallBaseLine.x1 } + newPEnd = { y: roofLine.y2, x: roofLine.x2 } + + }else if (wallBaseLine.x2 <= newPEnd.x && newPEnd.x <= wallBaseLine.x1 && wallBaseLine.x1 <= newPStart.x) { //right / top + + newPStart = { y: roofLine.y1, x: roofLine.x1 } + newPEnd = { y: roofLine.y2, x: (isCross) ? currentRoofLine.x1 : wallBaseLine.x1 } + } + + //newPEnd = { x: (isCross) ? currentRoofLine.x1 : origin.x1, y: roofLine.y1 } //수직라인 접점까지지 } - //movedLines.push({ index, newPStart, newPEnd }) - console.log("moveStart:::::::::::::", origin, newPStart, newPEnd) getAddLine(newPStart, newPEnd, 'green') - +//movedLines.push({ index, newPStart, newPEnd }) + console.log("moveStart:::::::::::::", origin, newPStart, newPEnd) } else if (movedEnd) { //start변경 //반시계방향 - newPStart = { x: roofLine.x2, y: roofLine.y2 } + if (getOrientation(roofLine) === 'vertical') { @@ -953,8 +1050,37 @@ if(roof.moveUpDown??0 > 0) { if (Math.abs(currentRoofLine.x2 - roofLine.x1) < 0.1 || Math.abs(currentRoofLine.x1 - roofLine.x2) < 0.1) { isCross = true; } - //newPStart = { x: roofLine.x1, y: roofLine.y1 } - newPEnd = { x: roofLine.x2, y: (isCross) ? currentRoofLine.y2 : origin.y2 } //수직라인 접점까지지 + + if(newPStart.y <= wallBaseLine.y1 && wallBaseLine.y1 < wallBaseLine.y2 && wallBaseLine.y2 < newPEnd.y){//bottom leftv + newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y2 : wallBaseLine.y2 } + newPEnd = { x: roofLine.x2, y: roofLine.y2 } + + }else if(newPEnd.y <= wallBaseLine.y2 && wallBaseLine.y2 < wallBaseLine.y1 && wallBaseLine.y1 <= newPStart.y){ //top /right + newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y2 : wallBaseLine.y2 } + newPEnd = { x: roofLine.x2, y: roofLine.y2 } + + }else if(newPEnd.y <= wallBaseLine.y2 && wallBaseLine.y2 <= newPStart.y && newPStart.y <= wallBaseLine.y1) { //top / left + + newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y2 : wallBaseLine.y2 } + newPEnd ={ x: roofLine.x2, y: roofLine.y2 } + + }else if(newPStart.y <= wallBaseLine.y1 && wallBaseLine.y1 <= newPEnd.y && newPEnd.y <= wallBaseLine.y2) {//top / righty 오르쪽v + + newPStart = { x: roofLine.x1, y: roofLine.y1 } + newPEnd = { x: roofLine.x2, y: (isCross) ? currentRoofLine.y2 : wallBaseLine.y2 } + + }else if(wallBaseLine.y1 <= newPStart.y && newPStart.y <= wallBaseLine.y2 && wallBaseLine.y2 <= newPEnd.y) { //하단 오른쪽v + + newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y1 : wallBaseLine.y1 } + newPEnd = { x: roofLine.x2, y: roofLine.y2 } + + }else if (wallBaseLine.y2 <= newPEnd.y && newPEnd.y <= wallBaseLine.y1 && wallBaseLine.y1 <= newPStart.y) { //하단 왼쪽 + + newPStart = { x: roofLine.x1, y: roofLine.y1 } + newPEnd = { x: roofLine.x2, y: (isCross) ? currentRoofLine.y2 : wallBaseLine.y2 } + } + + } else if (getOrientation(roofLine) === 'horizontal') { @@ -963,7 +1089,37 @@ if(roof.moveUpDown??0 > 0) { isCross = true; } - newPEnd = { x: (isCross) ? currentRoofLine.x2 : origin.x2, y: roofLine.y2 } //수직라인 접점까지지 + if(newPStart.x <= wallBaseLine.x1 && wallBaseLine.x1 < wallBaseLine.x2 && wallBaseLine.x2 < newPEnd.x){//right / bottom + newPStart = { y: roofLine.y1, x: (isCross) ? currentRoofLine.x2 : wallBaseLine.x2 } + newPEnd = { y: roofLine.y2, x: roofLine.x2 } + + }else if(newPEnd.x <= wallBaseLine.x2 && wallBaseLine.x2 < wallBaseLine.x1 && wallBaseLine.x1 <= newPStart.x){ //left / top + newPStart = { y: roofLine.y1, x: (isCross) ? currentRoofLine.x2 : wallBaseLine.x2 } + newPEnd = { y: roofLine.y2, x: roofLine.x2 } + + }else if(newPEnd.x <= wallBaseLine.x2 && wallBaseLine.x2 <= newPStart.x && newPStart.x <= wallBaseLine.x1) { //left top + + newPStart = { y: roofLine.y1, x: (isCross) ? currentRoofLine.x2 : wallBaseLine.x2 } + newPEnd ={ y: roofLine.y2, x: roofLine.x2 } + + }else if(newPStart.x <= wallBaseLine.x1 && wallBaseLine.x1 <= newPEnd.x && newPEnd.x <= wallBaseLine.x2) {//상단 오르쪽v + + newPStart = { y: roofLine.y1, x: roofLine.x1 } + newPEnd = { y: roofLine.y2, x: (isCross) ? currentRoofLine.x2 : wallBaseLine.x2 } + + }else if(wallBaseLine.x1 <= newPStart.x && newPStart.x <= wallBaseLine.x2 && wallBaseLine.x2 <= newPEnd.x) { //하단 오른쪽v + + newPStart = { y: roofLine.y1, x: (isCross) ? currentRoofLine.x1 : wallBaseLine.x1 } + newPEnd = { y: roofLine.y2, x: roofLine.x2 } + + }else if (wallBaseLine.x2 <= newPEnd.x && newPEnd.x <= wallBaseLine.x1 && wallBaseLine.x1 <= newPStart.x) { //하단 왼쪽 + + newPStart = { y: roofLine.y1, x: roofLine.x1 } + newPEnd = { y: roofLine.y2, x: (isCross) ? currentRoofLine.x2 : wallBaseLine.x2 } + } + + // newPStart = { x: roofLine.x2, y: roofLine.y2 } + // newPEnd = { x: (isCross) ? currentRoofLine.x2 : origin.x2, y: roofLine.y2 } //수직라인 접점까지지 } console.log("movedEnd:::::::::::::", origin, newPStart, newPEnd) @@ -3563,4 +3719,71 @@ function mergeTwoLines(line1, line2, type) { } }; } -} \ No newline at end of file +} + + +/** + * Adjusts line points based on movement type and orientation + * @param {Object} params - Configuration object + * @param {Object} params.roofLine - The original roof line + * @param {Object} params.currentRoofLine - The current roof line after movement + * @param {Object} params.wallBaseLine - The wall base line + * @param {Object} params.origin - The original position before movement + * @param {string} params.moveType - Type of movement: 'start' | 'end' | 'both' + * @returns {{newPStart: {x: number, y: number}, newPEnd: {x: number, y: number}}} + */ +function adjustLinePoints({ roofLine, currentRoofLine, wallBaseLine, origin, moveType }) { + const isHorizontal = getOrientation(roofLine) === 'horizontal'; + const isVertical = !isHorizontal; + + // Initialize points + let newPStart = { x: roofLine.x1, y: roofLine.y1 }; + let newPEnd = { x: roofLine.x2, y: roofLine.y2 }; + + // Check if lines cross (same as original isCross logic) + let isCross = false; + if (isVertical) { + isCross = Math.abs(currentRoofLine.x2 - roofLine.x1) < 0.1 || + Math.abs(currentRoofLine.x1 - roofLine.x2) < 0.1; + } else { + isCross = Math.abs(currentRoofLine.y1 - roofLine.y2) < 0.1 || + Math.abs(currentRoofLine.y2 - roofLine.y1) < 0.1; + } + + // Determine which points to adjust + const adjustStart = moveType === 'start' || moveType === 'both'; + const adjustEnd = moveType === 'end' || moveType === 'both'; + + if (isVertical) { + // Vertical line adjustments + if (adjustStart) { + newPStart = { + x: roofLine.x1, + y: isCross ? currentRoofLine.y1 : wallBaseLine.y1 + }; + } + if (adjustEnd) { + newPEnd = { + x: roofLine.x2, + y: isCross ? currentRoofLine.y2 : wallBaseLine.y2 + }; + } + } else { + // Horizontal line adjustments + if (adjustStart) { + newPStart = { + y: roofLine.y1, + x: isCross ? currentRoofLine.x1 : wallBaseLine.x1 + }; + } + if (adjustEnd) { + newPEnd = { + y: roofLine.y2, + x: isCross ? currentRoofLine.x2 : wallBaseLine.x2 + }; + } + } + + return { newPStart, newPEnd }; +} +