From 064c87a65540f5a74772621dc00e20fc216b0a50 Mon Sep 17 00:00:00 2001 From: ysCha Date: Tue, 18 Nov 2025 18:18:51 +0900 Subject: [PATCH] sk line --- src/util/skeleton-utils.js | 531 +++++++++++-------------------------- 1 file changed, 149 insertions(+), 382 deletions(-) diff --git a/src/util/skeleton-utils.js b/src/util/skeleton-utils.js index f48b75ef..ed6683cd 100644 --- a/src/util/skeleton-utils.js +++ b/src/util/skeleton-utils.js @@ -567,336 +567,17 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { canvas?.add(coordinateText) //skeleton 라인에서 처마선은 삭제 - if(innerLine.lineName !== 'outerLine'){ + if(innerLine.lineName === 'outerLine'){ }else{ - // let p3, p4 - // let idx = 0; - // let isMoveLine = true; - // for(const roofLine of roof.lines){ - // if(isSamePoint(p1, roofLine.startPoint) || isSamePoint(p2, roofLine.endPoint)){ - // console.log("outerLine1:::::", p1, p2, roofLine, idx) - // isMoveLine = false; - // break; - // }else if(isSamePoint(p1, roofLine.endPoint) || isSamePoint(p2, roofLine.startPoint)){ - // console.log("outerLine2:::::", p1, p2, roofLine, idx) - // isMoveLine = false; - // break; - // } - // } - // if(isMoveLine){ - // const p1RoofLine = findClosestRoofLine(p1,roof.lines) - // const p2RoofLine = findClosestRoofLine(p2,roof.lines) - // const p1wallLine = findClosestRoofLine(p1,wall.lines) - // const p2wallLine = findClosestRoofLine(p2,wall.lines) - // - // console.log("p1RoofLineV",p1RoofLine) - // console.log("p2RoofLineV",p2RoofLine) - // console.log("p1wallLineV",p1wallLine) - // console.log("p2wallLineV",p2wallLine) - // - // - // if(p1RoofLine.distance > 0 && p2RoofLine.distance === 0){ - // console.log("A:::") - // // p1 = p1RoofLine.line.startPoint - // // p2 = p1RoofLine.line.endPoint - // p3 = p1wallLine.line.endPoint - // p4 = p1wallLine.line.startPoint - // }else if(p1RoofLine.distance === 0 && p2RoofLine.distance > 0){ - // console.log("B:::") - // // p1 = p2RoofLine.line.startPoint - // // p2 = p2RoofLine.line.endPoint - // - // p3 = p2wallLine.line.endPoint - // p4 = p2wallLine.line.startPoint - // } else if(p1RoofLine.distance > 0 && p2RoofLine.distance > 0){ - // if(p1RoofLine.distance > p2RoofLine.distance){ - // console.log("C-1:::") - // p1 = p1RoofLine.line.startPoint - // p2 = p1RoofLine.line.endPoint - // p3 = p1wallLine.line.endPoint - // p4 = p1wallLine.line.startPoint - // }else{ - // console.log("C-2:::") - // p1 = p2RoofLine.line.startPoint - // p2 = p2RoofLine.line.endPoint - // p3 = p2wallLine.line.endPoint - // p4 = p2wallLine.line.startPoint - // } - // } - // - // - // // const wallLine = wall.baseLines[roofLine.idx - 1]; - // - // - // // if(p1RoofLine.distance > p2RoofLine.distance){ - // // p1 = p2RoofLine.line.endPoint //loofLine.startPoint - // // p3 = p2RoofLine.line.endPoint //wallLine.startPoint - // // p2 = { x: p1.x, y: p3.y } //x고정, y변동 - // // p4 = { x: p3.x, y: p1.y } //x변동 y고정 - // // }else{ - // // p1 = loofLine.startPoint //loofLine.startPoint - // // p3 = wallLine.startPoint //wallLine.startPoint - // // p2 = { x: p3.x, y: p1.y } //x고정, y변동 - // // p4 = { x: p1.x, y: p3.y } //x변동 y고정 - // // } - // - // - // //wallLine이 baseLine의 위 또는 오른쪽에 있을때 - // const rect = new QPolygon([p1, p2, p3, p4], { - // type: POLYGON_TYPE.ROOF, - // fill: 'transparent', - // stroke: 'red', - // strokeWidth: 2, - // selectable: false, - // evented: false, - // }) - // canvas.add(rect) - // canvas.renderAll() - // } + } - // if(innerLine.lineName === 'outerLine'){ - // //line은 시계방향이다.p1 -> p2 - // - // let idx = 0; - // //const orgWallLine = wall.lines - // //console.log("outLine:::::", p1, p2, line) - // - // let lineExists = false; - // - // for (const orgLine of roof.lines) { - // const sameDirection = isSamePoint(p1, orgLine.startPoint) && isSamePoint(p2, orgLine.endPoint); - // const oppositeDirection = isSamePoint(p2, orgLine.startPoint) && isSamePoint(p1, orgLine.endPoint); - // - // if (sameDirection || oppositeDirection) { - // lineExists = true; - // break; // 같은 라인이 발견되면 즉시 순환 종료 - // } - // } - // - // if (!lineExists) { - // - // let p1Line = findClosestRoofLine(p1, roof.lines) - // let p2Line = findClosestRoofLine(p2, roof.lines) - // - // let p1wallLine = findClosestRoofLine(p1, wall.baseLines) - // let p2wallLine = findClosestRoofLine(p2, wall.baseLines) - // - // console.log("p1LineV",p1Line) - // console.log("p2LineV",p2Line) - // console.log("p1wallLineV",p1wallLine) - // console.log("p2wallLineV",p2wallLine) - // //skt는 시계방향 p1 -> p2 - // //와곽라인은 시계, 반시계 - // // - // - // - // //외벽선과 접점이 없으면 - // if(p1Line.distance > 0 && p2Line.distance > 0) { - // - // } - // if(p1Line.distance === 0 && p2Line.distance === 0) { - // return - // } - // - // console.log("p1Line.line.startPoint.x:::::",p1Line.line.startPoint) - // console.log("p1Line.line.endPoint.x:::::",p1Line.line.endPoint) - // console.log("p2Line.line.startPoint.x:::::",p2Line.line.startPoint) - // console.log("p2Line.line.endPoint.x:::::",p2Line.line.endPoint) - // - // console.log("p1,p2:::::",p1, p2) - // - // if(isSamePoint(p1, p1Line.line.startPoint) || isSamePoint(p1, p1Line.line.endPoint)) { - // //p1.y = p2wallLine.line.endPoint.y - // return - // - // } - // if(isSamePoint(p2, p2Line.line.startPoint) || isSamePoint(p2, p2Line.line.endPoint)) { - // //p2.y = p1wallLine.line.endPoint.y - // return - // } - // - // - // if(p1Line.distance > 0 && p2Line.distance === 0 ){ - // console.log("수평이면 수평을 연장") - // - // // p1.x = p1Line.line.endPoint.x - // // p1.y = p1Line.line.endPoint.y - // // p2.x = p1wallLine.line.endPoint.y - // // p2.y = - // - // - // } - // if(p1Line.distance === 0 && p2Line.distance > 0 ) { - // - // console.log("수직이면 수평을 연장") - // // p1.x = p2Line.line.endPoint.x - // // p1.y = p2Line.line.endPoint.y - // // p2.x = p1wallLine.line.endPoint.x - // // p2.y = p1.y - // - // } - // - // - // const orgP1 = { ...p1 }; - // const orgP2 = { ...p2 }; - // let p3,p4; - // - // let roofIdx = p2Line.index - // const changeLine = roof.lines[roofIdx] - // const changeWallLine = wall.baseLines[roofIdx] - // - // p1 = p2Line.line.endPoint //changeLine.startPoint - // p2.x = changeWallLine.endPoint.x - // p2.y = changeLine.startPoint.y - // if(Math.abs(orgP2.y - changeLine.endPoint.y) < 0.1){ - // p2 = orgP2 - // - // } - // - // if(p1Line.distance > p2Line.distance){ - // //반시계 - // roofIdx = p1Line.index - // const changeLine2 = roof.lines[roofIdx] - // const changeWallLine2 = wall.baseLines[roofIdx] - // p1 = p1Line.line.endPoint.x//changeLine2.endPoint - // p2.x = changeLine2.endPoint.x - // p2.y = changeWallLine2.startPoint.y - // if(Math.abs(orgP1.x - changeLine2.endPoint.x) < 0.1){ - // p2 = orgP1 - // } - // } - // - // - // if (Array.isArray(addLines)) { - // // 이미 동일한 p1, p2를 가진 객체가 있는지 확인 - // const isDuplicate = addLines.some(line => - // (line.p1.x === p1.x && line.p1.y === p1.y && - // line.p2.x === p2.x && line.p2.y === p2.y) || - // (line.p1.x === p2.x && line.p1.y === p2.y && - // line.p2.x === p1.x && line.p2.y === p1.y) - // ); - // - // if (isDuplicate) { - // return; // 중복된 라인이 있으면 함수 종료 - // } - // - // // 중복이 없으면 추가 - // addLines.push({p1, p2}); - // - // - // - // if(addLines.length === 2){ - // - // //기존 라인삭제 - // - // const existingNewLine2 = canvas.getObjects().find(obj => obj.lineName === "helpLine"); - // if (existingNewLine2) { - // canvas.remove(existingNewLine2); - // canvas.renderAll(); - // } - // const line1 = addLines[0]; - // const line2 = addLines[1]; - // // Find the common point (the vertex of the right angle) - // let commonPoint, p3, p4; - // - // if (line1.p1.x === line2.p1.x || line1.p1.x === line2.p2.x) { - // commonPoint = line1.p1; - // } else { - // commonPoint = line1.p2; - // } - // - // // Find the other two points - // const otherPoint1 = line1.p1 === commonPoint ? line1.p2 : line1.p1; - // const otherPoint2 = line2.p1 === commonPoint ? line2.p2 : line2.p1; - // - // // Calculate the fourth point to form a rectangle - // p3 = { - // x: otherPoint1.x + (otherPoint2.x - commonPoint.x), - // y: otherPoint1.y + (otherPoint2.y - commonPoint.y) - // }; - // - // // Create the rectangle points in order (clockwise or counter-clockwise) - // const rectPoints = [commonPoint, otherPoint1, p3, otherPoint2]; - // - // const rect = new QPolygon(rectPoints, { - // type: POLYGON_TYPE.ROOF, - // fill: 'transparent', - // stroke: 'black', - // strokeWidth: 2, - // selectable: false, - // evented: false - // }); - // canvas.add(rect); - // canvas.renderAll(); - // return; - // } - // } - // - // const lineId = `${p1.x},${p1.y}-${p2.x},${p2.y}`; - // - // - // const newLine2 = new QLine( - // [p1.x, p1.y, p2.x, p2.y], - // { - // parentId : roof.id, - // fontSize : roof.fontSize, - // stroke : 'black', - // strokeWidth: 2, - // name : 'auxiliaryLine', - // attributes : attributes, - // direction : direction, - // isBaseLine : sktLine.attributes.isOuterEdge, - // lineName : 'helpLine', - // isFixed: true, - // selectable : true, - // roofId : roofId, - // lineId: lineId - // - // } - // ); - // - // canvas.add(newLine2); - // } - // - // - // //초기외곽라인? - // const coordinateText = new fabric.Text(`(${Math.round(p1.x)}, ${Math.round(p1.y)})`, { - // left: p1.x + 5, // 좌표점에서 약간 오른쪽으로 이동 - // top: p1.y - 20, // 좌표점에서 약간 위로 이동 - // fontSize: 13, - // fill: 'red', - // fontFamily: 'Arial', - // selectable: true, - // lockMovementX: false, - // lockMovementY: false, - // lockRotation: true, - // lockScalingX: true, - // lockScalingY: true, - // name: 'lengthText' - // }) - // - // canvas?.add(coordinateText) - // - // }else{ - // - // canvas.add(innerLine); - // innerLine.bringToFront(); - // existingLines.add(lineKey); // 추가된 라인을 추적 - // } + innerLines.push(innerLine) canvas.renderAll(); }); - // let outerLinePoints = canvas.getObjects().filter((obj) => obj.name === 'outerLinePoint' ) - // outerLinePoints.forEach((outerLinePoint) => { - // canvas.remove(outerLinePoint) - // canvas.renderAll() - // }); - // - - // 같은 라인이 없으므로 새 다각형 라인 생성 //라인 편집 @@ -934,6 +615,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { const currentOuterLines = canvas .getObjects() .filter((obj) => obj.lineName === 'outerLine' && obj.roofId === roofId) + const roofLine = roof.lines[index]; const p1RoofLine = findClosestRoofLine(wallLineStartPoint,roof.lines) const p2RoofLine = findClosestRoofLine(wallLineEndPoint,roof.lines) @@ -941,8 +623,8 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { const p1wallLine = findClosestRoofLine(wallLineStartPoint,wall.lines) const p2wallLine = findClosestRoofLine(wallLineEndPoint,wall.lines) - const p1outerLine = findClosestRoofLine(wallLineStartPoint,currentOuterLines) - const p2outerLine = findClosestRoofLine(wallLineEndPoint,currentOuterLines) + const p1outerLine = findClosestRoofLine(wallLineStartPoint, currentOuterLines) + const p2outerLine = findClosestRoofLine(wallLineEndPoint, currentOuterLines) console.log("p1RoofLineV",p1RoofLine) @@ -957,69 +639,154 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { // canvas.renderAll() -currentOuterLines.forEach((line) => { - line.set('stroke', 'green') // 원하는 색으로 변경 -}) + // currentOuterLines.forEach((line) => { + // line.set('stroke', 'green') // 원하는 색으로 변경 + // }) + // + // if (currentOuterLines.length > 0) { + // canvas.requestRenderAll() + // } + // const candidates = canvas.getObjects().filter((obj) => obj.roofId === roofId) + // console.log('candidates', candidates.map((obj) => obj.lineName)) -if (currentOuterLines.length > 0) { - canvas.requestRenderAll() -} - const candidates = canvas.getObjects().filter((obj) => obj.roofId === roofId) - console.log('candidates', candidates.map((obj) => obj.lineName)) - - if(p1RoofLine.distance > 0 && p2RoofLine.distance === 0){ - console.log("A:::") - p1 = roofLine.startPoint - p2 = roofLine.endPoint - p3 = wallLine.endPoint - p4 = wallLine.startPoint - - }else if(p1RoofLine.distance === 0 && p2RoofLine.distance > 0){ - console.log("B:::") - p1 = roofLine.endPoint - p2 = roofLine.startPoint - p3 = wallLine.startPoint - p4 = wallLine.endPoint - - } else if(p1RoofLine.distance > 0 && p2RoofLine.distance > 0){ - if(p1RoofLine.distance > p2RoofLine.distance){ - console.log("C-1:::") - p1 = roofLine.startPoint - p2 = roofLine.endPoint - p3 = wallLine.endPoint - p4 = wallLine.startPoint - - console.log("C-1-1:::",roofLine.startPoint, wallLineStartPoint, wallLine.endPoint, wallLine.x1, wallLine.x2) - - p1 = roofLine.startPoint - //wallLine.startLine은 변경된 라인이 아니라 이전 라인의 값을 가지고 있음 그래서 x1, x2 사용 - p3 = wallLineStartPoint - p2.x = p3.x - p2.y = p1.y - p4.x = p1.x - p4.y = (p1outerLine?.intersectionPoint.x === p1.x)?p1outerLine?.intersectionPoint.y:p3.y - - console.log("p1,p2:::::",p1, p2, p3,p4) - canvas.remove(p1outerLine.line) + const addHelpLine = (roofLine, wallLine, outerLineA, outerLineB) => { + //반시계방향 + const roofLineStartPoint = {x:roofLine.x1, y:roofLine.y1} + const roofLineEndPoint = {x:roofLine.x2, y:roofLine.y2} + const wallLineStartPoint = {x:wallLine.x1, y:wallLine.y1} + const wallLineEndPoint = {x:wallLine.x2, y:wallLine.y2} + const isVertical = wallLineStartPoint.x === wallLineEndPoint.x; + let newP1, newP2, newP3, newP4; + if(isVertical){ + newP1 = roofLineStartPoint + newP3 = wallLineStartPoint + newP2 = {x:newP1.x, y: newP3.y} + newP4 = {x:Math.abs(outerLineA?.intersectionPoint.y - newP1.y) < 0.1 ? outerLineA?.intersectionPoint.x : newP3.x, y:newP1.y} }else{ - console.log("C-2:::") - p1 = roofLine.endPoint - p2 = roofLine.startPoint - p3 = wallLine.startPoint - p4 = wallLine.endPoint - - p1 = roofLine.endPoint - //wallLine.startLine은 변경된 라인이 아니라 이전 라인의 값을 가지고 있음 그래서 x1, x2 사용 - p3 = wallLineEndPoint - p2.x = p3.x - p2.y = p1.y - p4.x = p1.x - p4.y = p3.y - + newP1 = roofLineStartPoint + newP3 = wallLineStartPoint + newP2 = {x:newP3.x, y: newP1.y} + newP4 = {x:newP1.x, y: (Math.abs(outerLineA?.intersectionPoint.x - newP1.x) < 0.1) ? outerLineA?.intersectionPoint.y : newP3.y} } - } + return {newP1, newP2, newP3, newP4} + + }; + + const addHelpLine2 = (roofLine, wallLine, outerLineA, outerLineB) => { + //반시계방향 + const roofLineStartPoint = {x:roofLine.x1, y:roofLine.y1} + const roofLineEndPoint = {x:roofLine.x2, y:roofLine.y2} + const wallLineStartPoint = {x:wallLine.x1, y:wallLine.y1} + const wallLineEndPoint = {x:wallLine.x2, y:wallLine.y2} + const isVertical = wallLineStartPoint.x === wallLineEndPoint.x; + + let newP1, newP2, newP3, newP4; + if(isVertical){ + newP1 = roofLineEndPoint + newP3 = wallLineEndPoint + newP2 = {x:newP1.x, y: newP3.y} + newP4 = {x:Math.abs(outerLineB?.intersectionPoint.y - newP1.y) < 0.1 ? outerLineB?.intersectionPoint.x : newP3.x, y:newP1.y} + }else{ + newP1 = roofLineEndPoint + newP3 = wallLineEndPoint + newP2 = {x:newP3.x, y: newP1.y} + newP4 = {x:newP1.x, y: (Math.abs(outerLineB?.intersectionPoint.x - newP1.x) < 0.1) ? outerLineB?.intersectionPoint.y : newP3.y} + + } + return {newP1, newP2, newP3, newP4} + + }; + + if(p1wallLine.distance > 0 && p2wallLine.distance === 0) { + + console.log("왼쪽 수평 / 오른쪽 수직") + const changeLine = addHelpLine(roofLine, wallLine, p1outerLine, p2outerLine) + + p1 = changeLine.newP1 + p2 = changeLine.newP2 + p3 = changeLine.newP3 + p4 = changeLine.newP4 + + canvas.remove(p1outerLine.line) + canvas.remove(p2outerLine.line) + + }else if(p2wallLine.distance > 0 && p1wallLine.distance === 0) { + console.log("오른쪽 수평 / 왼쪽 수직") + const changeLine = addHelpLine2(roofLine, wallLine, p1outerLine, p2outerLine) + + p1 = changeLine.newP1 + p2 = changeLine.newP2 + p3 = changeLine.newP3 + p4 = changeLine.newP4 + + canvas.remove(p1outerLine.line) + canvas.remove(p2outerLine.line) + }else if(p2wallLine.distance > 0 && p2wallLine.distance === 0) { + + console.log("1p1wallLine.distance", p1wallLine.distance); + console.log("1p2wallLine.distance", p2wallLine.distance); + + + }else { + console.log("p1wallLine.distance", p1wallLine.distance); + console.log("p2wallLine.distance", p2wallLine.distance); + } + // if(p1RoofLine.distance > 0 && p2RoofLine.distance === 0){ + // console.log("A:::") + // p1 = roofLine.startPoint + // p2 = roofLine.endPoint + // p3 = wallLine.endPoint + // p4 = wallLine.startPoint + // + // }else if(p1RoofLine.distance === 0 && p2RoofLine.distance > 0){ + // console.log("B:::") + // p1 = roofLine.endPoint + // p2 = roofLine.startPoint + // p3 = wallLine.startPoint + // p4 = wallLine.endPoint + // + // } else if(p1RoofLine.distance > 0 && p2RoofLine.distance > 0){ + // if(p1RoofLine.distance > p2RoofLine.distance){ + // console.log("C-1:::") + // p1 = roofLine.startPoint + // p2 = roofLine.endPoint + // p3 = wallLine.endPoint + // p4 = wallLine.startPoint + // + // console.log("C-1-1:::",roofLine.startPoint, wallLineStartPoint, wallLine.endPoint, wallLine.x1, wallLine.x2) + // + // p1 = {...roofLine.startPoint} + // //wallLine.startLine은 변경된 라인이 아니라 이전 라인의 값을 가지고 있음 그래서 x1, x2 사용 + // p3 = {...wallLineStartPoint} + // p2.x = p3.x + // p2.y = p1.y + // p4.x = p1.x + // p4.y = (Math.abs(p1outerLine?.intersectionPoint.x - p1.x) < 0.1) ? p1outerLine?.intersectionPoint.y : p3.y + // + // console.log("11111p1,p2:::::",p1, p2, p3,p4) + // canvas.remove(p1outerLine.line) + // + // }else{ + // console.log("C-2:::") + // p1 = roofLine.endPoint + // p2 = roofLine.startPoint + // p3 = wallLine.startPoint + // p4 = wallLine.endPoint + // + // p1 = {...roofLine.endPoint} + // //wallLine.startLine은 변경된 라인이 아니라 이전 라인의 값을 가지고 있음 그래서 x1, x2 사용 + // p3 = {...wallLineEndPoint} + // p2.x = p3.x + // p2.y = p1.y + // p4.x = p1.x + // p4.y = (Math.abs(p2outerLine?.intersectionPoint.x - p1.x) < 0.1) ? p2outerLine?.intersectionPoint.y : p3.y + // console.log("22222p1,p2:::::",p1, p2, p3,p4) + // canvas.remove(p2outerLine.line) + // + // } + //targetLines를 p1, p2 로 바꾸고 싶다.. const editLine = (targetLines, p1, p2) => {