From 0bc0e73a103bd46113320c202b87eac4265eb0e8 Mon Sep 17 00:00:00 2001 From: Jaeyoung Lee Date: Fri, 18 Oct 2024 10:29:31 +0900 Subject: [PATCH] =?UTF-8?q?=EC=A7=80=EB=B6=95=20=EB=AA=A8=EC=96=91=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20=EC=9E=91=EC=97=85=20=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/common.js | 1 + src/components/Roof2.jsx | 45 +++++--- src/hooks/useMode.js | 43 +++++++- src/util/qpolygon-utils.js | 205 +++++++++++++++++++++++-------------- 4 files changed, 197 insertions(+), 97 deletions(-) diff --git a/src/common/common.js b/src/common/common.js index ae96db06..bc067077 100644 --- a/src/common/common.js +++ b/src/common/common.js @@ -63,6 +63,7 @@ export const LINE_TYPE = { HIPANDGABLE: 'hipAndGable', JERKINHEAD: 'jerkinhead', SHED: 'shed', + ETC: 'etc', }, SUBLINE: { /** diff --git a/src/components/Roof2.jsx b/src/components/Roof2.jsx index 910fd365..2fe86ecc 100644 --- a/src/components/Roof2.jsx +++ b/src/components/Roof2.jsx @@ -4,7 +4,7 @@ import { useCanvas } from '@/hooks/useCanvas' import { useEffect, useRef, useState } from 'react' import { v4 as uuidv4 } from 'uuid' import { useMode } from '@/hooks/useMode' -import { Mode } from '@/common/common' +import { LINE_TYPE, Mode } from '@/common/common' import { Button, Input } from '@nextui-org/react' import RangeSlider from './ui/RangeSlider' import { useRecoilState, useRecoilValue } from 'recoil' @@ -39,7 +39,7 @@ import QEmptyContextMenu from '@/components/common/context-menu/QEmptyContextMen import InitSettingsModal from './InitSettingsModal' import GridSettingsModal from './GridSettingsModal' import { SurfaceShapeModal } from '@/components/ui/SurfaceShape' -import { drawDirectionStringToArrow } from '@/util/qpolygon-utils' +import { changeHipAndGableRoof, drawDirectionStringToArrow } from '@/util/qpolygon-utils' import ThumbnailList from '@/components/ui/ThumbnailLIst' import ObjectPlacement from '@/components/ui/ObjectPlacement' import { globalLocaleStore } from '@/store/localeAtom' @@ -431,7 +431,7 @@ export default function Roof2(props) { { x: 450, y: 850 }, ] - const polygon = new QPolygon(rectangleType2, { + const polygon = new QPolygon(rectangleType1, { fill: 'transparent', stroke: 'green', strokeWidth: 1, @@ -672,13 +672,14 @@ export default function Roof2(props) { canvas?.renderAll() } - const setAllGableRoof = () => { + const setGableRoof = () => { let offset = Number(prompt('gable roof offset', '50')) if (!isNaN(offset) && offset > 0) { - const polygon = canvas?.getObjects() - console.log('gable roof offset : ', offset) - console.log('polygon : ', polygon) - changeAllGableRoof(polygon, offset, canvas) + const polygon = canvas?.getObjects().find((obj) => obj.name === 'roof') + const currentRoof = polygon.lines[3] + currentRoof.attributes.type = LINE_TYPE.WALLLINE.HIPANDGABLE + currentRoof.attributes.width = offset + changeHipAndGableRoof(currentRoof, canvas) } else { alert('offset 은 0 보다 커야 함') } @@ -802,16 +803,28 @@ export default function Roof2(props) { - {templateType === 0 && ( - <> - - - )} - + {/* */} + {/*)}*/} + + + + + diff --git a/src/hooks/useMode.js b/src/hooks/useMode.js index e7b457e5..6a332d35 100644 --- a/src/hooks/useMode.js +++ b/src/hooks/useMode.js @@ -36,10 +36,7 @@ import { QPolygon } from '@/components/fabric/QPolygon' import offsetPolygon from '@/util/qpolygon-utils' import { isObjectNotEmpty } from '@/util/common-utils' import * as turf from '@turf/turf' -import { INPUT_TYPE, Mode } from '@/common/common' -import { m } from 'framer-motion' -import { set } from 'react-hook-form' -import { FaWineGlassEmpty } from 'react-icons/fa6' +import { INPUT_TYPE, LINE_TYPE, Mode } from '@/common/common' export function useMode() { const [mode, setMode] = useRecoilState(modeState) @@ -1509,6 +1506,43 @@ export function useMode() { *벽 지붕 외곽선 생성 polygon을 입력받아 만들기 */ const handleOuterlinesTest2 = (polygon, offset = 50) => { + console.log('polygon : ', polygon) + // TODO [ljyoung] : offset 입력 처리 후 제거 해야함. + polygon.lines.forEach((line, index) => { + line.attributes = { + type: LINE_TYPE.WALLLINE.EAVES, + offset: 40, + width: 50, + pitch: 4, + sleeve: true, + } + /*if (index === 1 || index === 3) { + line.attributes = { + type: LINE_TYPE.WALLLINE.WALL, + offset: 0, //출폭 + width: 30, //폭 + pitch: 4, //구배 + sleeve: true, //소매 + } + } else if (index === 0) { + line.attributes = { + type: LINE_TYPE.WALLLINE.EAVES, + offset: 0, + width: 50, + pitch: 4, + sleeve: true, + } + } else { + line.attributes = { + type: LINE_TYPE.WALLLINE.EAVES, + offset: 40, + width: 50, + pitch: 4, + sleeve: true, + } + }*/ + }) + const roof = drawRoofPolygon(polygon) //지붕 그리기 roof.drawHelpLine() // roof.divideLine() @@ -1706,6 +1740,7 @@ export function useMode() { offset: wall.lines[index].attributes.offset, width: wall.lines[index].attributes.width, pitch: wall.lines[index].attributes.pitch, + sleeve: wall.lines[index].attributes.sleeve || false, } }) diff --git a/src/util/qpolygon-utils.js b/src/util/qpolygon-utils.js index c7ccfece..62597365 100644 --- a/src/util/qpolygon-utils.js +++ b/src/util/qpolygon-utils.js @@ -2030,7 +2030,6 @@ const connectLinePoint = (polygon) => { } const modifyRidge = (roof, canvas) => { - const roofLines = roof.lines const ridgeLines = canvas?.getObjects().filter((object) => object.name === 'ridgeLine' && object.attributes.roofId === roof.id) const hipLines = canvas?.getObjects().filter((object) => object.name === 'hipLine' && object.attributes.roofId === roof.id) @@ -2041,7 +2040,6 @@ const modifyRidge = (roof, canvas) => { let currentRoof = roof.lines .filter((roofLine) => roofLine.attributes !== undefined && roofLine.attributes.ridgeCoordinate !== undefined) .find((roofLine) => roofLine.attributes.ridgeCoordinate.x1 === ridge.x1 && roofLine.attributes.ridgeCoordinate.y1 === ridge.y1) - console.log('1 currentRoof : ', currentRoof) if (currentRoof === undefined) { currentRoof = roof.lines.find( (roofLine) => @@ -2058,7 +2056,6 @@ const modifyRidge = (roof, canvas) => { currentRoof.attributes.ridgeCoordinate = { x1: ridge.x1, y1: ridge.y1 } } } - console.log('2 currentRoof : ', currentRoof) if (currentRoof !== undefined) { switch (currentRoof.attributes.type) { case LINE_TYPE.WALLLINE.EAVES: @@ -2067,7 +2064,7 @@ const modifyRidge = (roof, canvas) => { changeGableRoof(roof.id, currentRoof, canvas) break case LINE_TYPE.WALLLINE.HIPANDGABLE: - changeHipAndGableRoof(roof.id, currentRoof, canvas) + changeHipAndGableRoof(currentRoof, canvas) break case LINE_TYPE.WALLLINE.JERKINHEAD: changeJerkInHeadRoof(roof.id, currentRoof, canvas) @@ -2082,7 +2079,6 @@ const modifyRidge = (roof, canvas) => { let currentRoof = roof.lines .filter((roofLine) => roofLine.attributes !== undefined && roofLine.attributes.ridgeCoordinate !== undefined) .find((roofLine) => roofLine.attributes.ridgeCoordinate.x1 === ridge.x2 && roofLine.attributes.ridgeCoordinate.y1 === ridge.y2) - console.log('3 currentRoof : ', currentRoof) if (currentRoof === undefined) { currentRoof = roof.lines.find( (roofLine) => @@ -2099,7 +2095,6 @@ const modifyRidge = (roof, canvas) => { currentRoof.attributes.ridgeCoordinate = { x1: ridge.x2, y1: ridge.y2 } } } - console.log('4 currentRoof : ', currentRoof) if (currentRoof !== undefined) { switch (currentRoof.attributes.type) { case LINE_TYPE.WALLLINE.EAVES: @@ -2108,7 +2103,7 @@ const modifyRidge = (roof, canvas) => { changeGableRoof(roof.id, currentRoof, canvas) break case LINE_TYPE.WALLLINE.HIPANDGABLE: - changeHipAndGableRoof(roof.id, currentRoof, canvas) + changeHipAndGableRoof(currentRoof, canvas) break case LINE_TYPE.WALLLINE.JERKINHEAD: changeJerkInHeadRoof(roof.id, currentRoof, canvas) @@ -2220,12 +2215,12 @@ export const changeGableRoof = (roofId, currentRoof, canvas) => { /** * 팔작지붕으로 변경 - * @param roofId * @param currentRoof * @param canvas */ -export const changeHipAndGableRoof = (roofId, currentRoof, canvas) => { +export const changeHipAndGableRoof = (currentRoof, canvas) => { if (currentRoof.attributes.type === LINE_TYPE.WALLLINE.HIPANDGABLE) { + const roofId = currentRoof.attributes.roofId const roof = canvas?.getObjects().find((object) => object.name === 'roof' && object.id === roofId) let hipLines = canvas?.getObjects().filter((object) => object.name === 'hipLine' && object.attributes.roofId === roofId) let ridgeLines = canvas?.getObjects().filter((object) => object.name === 'ridgeLine' && object.attributes.roofId === roofId) @@ -2239,7 +2234,11 @@ export const changeHipAndGableRoof = (roofId, currentRoof, canvas) => { (hip) => (hip.x1 === currentRoof.x1 && hip.y1 === currentRoof.y1) || (hip.x1 === currentRoof.x2 && hip.y1 === currentRoof.y2), ) - if (ridgeLines.length > 0) { + hipLines.forEach((hip) => canvas?.remove(hip)) + + console.log(canvas?.getObjects().find((object) => object.attributes !== undefined && object.attributes.roofId === roofId)) + + /*if (ridgeLines.length > 0) { const ridge = ridgeLines[0] let midX = (currentRoof.x1 + currentRoof.x2) / 2 let midY = (currentRoof.y1 + currentRoof.y2) / 2 @@ -2310,7 +2309,7 @@ export const changeHipAndGableRoof = (roofId, currentRoof, canvas) => { roof.innerLines.push(hipLine) }) } - } + }*/ } } @@ -2426,8 +2425,13 @@ export const changeJerkInHeadRoof = (roofId, currentRoof, canvas) => { } } +/** + * 벽지붕으로 변경 + * @param roofId + * @param currentRoof + * @param canvas + */ const changeWallRoof = (roofId, currentRoof, canvas) => { - console.log('roofId : ', roofId) let roof = canvas?.getObjects().find((object) => object.name === 'roof' && object.id === roofId) const roofLines = roof.lines let prevRoof, nextRoof @@ -2444,6 +2448,10 @@ const changeWallRoof = (roofId, currentRoof, canvas) => { let hipLines = canvas?.getObjects().filter((object) => object.name === 'hipLine' && object.attributes.roofId === roofId) let ridgeLines = canvas?.getObjects().filter((object) => object.name === 'ridgeLine' && object.attributes.roofId === roofId) + if (wallLine.length > 0) { + wallLine = wallLine[0] + } + ridgeLines = ridgeLines.filter( (ridge) => (ridge.x1 === currentRoof.attributes.ridgeCoordinate.x1 && ridge.y1 === currentRoof.attributes.ridgeCoordinate.y1) || @@ -2453,8 +2461,8 @@ const changeWallRoof = (roofId, currentRoof, canvas) => { (hip) => (hip.x1 === currentRoof.x1 && hip.y1 === currentRoof.y1) || (hip.x1 === currentRoof.x2 && hip.y1 === currentRoof.y2), ) - const wallMidX = (wallLine[0].x1 + wallLine[0].x2) / 2 - const wallMidY = (wallLine[0].y1 + wallLine[0].y2) / 2 + const wallMidX = (wallLine.x1 + wallLine.x2) / 2 + const wallMidY = (wallLine.y1 + wallLine.y2) / 2 const roofMidX = (currentRoof.x1 + currentRoof.x2) / 2 const roofMidY = (currentRoof.y1 + currentRoof.y2) / 2 @@ -2482,7 +2490,88 @@ const changeWallRoof = (roofId, currentRoof, canvas) => { y2: nextRoof.y2, }) - reDrawPolygon(roof, canvas) + if (currentRoof.attributes.sleeve && prevRoof.attributes.offset > 0 && nextRoof.attributes.offset > 0) { + const prevSignX = Math.sign(prevRoof.x1 - prevRoof.x2) + const prevSignY = Math.sign(prevRoof.y1 - prevRoof.y2) + const nextSignX = Math.sign(nextRoof.x1 - nextRoof.x2) + const nextSignY = Math.sign(nextRoof.y1 - nextRoof.y2) + + const prevWidthX = prevSignX === 0 ? 0 : prevSignX * currentRoof.attributes.width + const prevWidthY = prevSignY === 0 ? 0 : prevSignY * currentRoof.attributes.width + const nextWidthX = nextSignX === 0 ? 0 : nextSignX * currentRoof.attributes.width + const nextWidthY = nextSignY === 0 ? 0 : nextSignY * currentRoof.attributes.width + const prevX2 = prevRoof.x2 - prevWidthX + const prevY2 = prevRoof.y2 - prevWidthY + const nextX1 = nextRoof.x1 + nextWidthX + const nextY1 = nextRoof.y1 + nextWidthY + + currentRoof.set({ + x1: wallLine.x1, + y1: wallLine.y1, + x2: wallLine.x2, + y2: wallLine.y2, + }) + + prevRoof.set({ + x1: prevRoof.x1, + y1: prevRoof.y1, + x2: prevX2, + y2: prevY2, + }) + + nextRoof.set({ + x1: nextX1, + y1: nextY1, + x2: nextRoof.x2, + y2: nextRoof.y2, + }) + + const addPrevWallLine1 = new QLine([prevX2, prevY2, wallLine.x1 - prevWidthX, wallLine.y1 - prevWidthY], { + fontSize: roof.fontSize, + stroke: 'red', + strokeWidth: 1, + name: 'roofLine', + attributes: { roofId: roofId, type: LINE_TYPE.WALLLINE.ETC }, + }) + + const addPrevWallLine2 = new QLine( + [addPrevWallLine1.x2, addPrevWallLine1.y2, addPrevWallLine1.x2 + prevWidthX, addPrevWallLine1.y2 + prevWidthY], + { + fontSize: roof.fontSize, + stroke: 'cyan', + strokeWidth: 1, + name: 'roofLine', + attributes: { roofId: roofId, type: LINE_TYPE.WALLLINE.ETC }, + }, + ) + + const addNextWallLine1 = new QLine([wallLine.x2, wallLine.y2, wallLine.x2 + nextWidthX, wallLine.y2 + nextWidthY], { + fontSize: roof.fontSize, + stroke: 'green', + strokeWidth: 1, + name: 'roofLine', + attributes: { roofId: roofId, type: LINE_TYPE.WALLLINE.ETC }, + }) + + const addNextWallLine2 = new QLine([addNextWallLine1.x2, addNextWallLine1.y2, nextX1, nextY1], { + fontSize: roof.fontSize, + stroke: 'red', + strokeWidth: 1, + name: 'roofLine', + attributes: { roofId: roofId, type: LINE_TYPE.WALLLINE.ETC }, + }) + + canvas?.renderAll() + const prevIndex = roof.lines.indexOf(prevRoof) + 1 + roof.lines.splice(prevIndex, 0, addPrevWallLine1, addPrevWallLine2) + + const nextIndex = roof.lines.indexOf(currentRoof) + 1 + roof.lines.splice(nextIndex, 0, addNextWallLine1, addNextWallLine2) + } + + roof = reDrawPolygon(roof, canvas) + + console.log('roof : ', roof.lines) if (ridgeLines.length > 0) { const ridge = ridgeLines[0] @@ -2508,72 +2597,31 @@ const changeWallRoof = (roofId, currentRoof, canvas) => { y2: ridge.y2 - diffY, }) } - } - console.log('hipLines : ', hipLines) + let hip1 = new QLine([currentRoof.x1, currentRoof.y1, wallMidX, wallMidY], { + fontSize: roof.fontSize, + stroke: 'red', + strokeWidth: 1, + name: 'hipLine', + attributes: { roofId: roof.id, currentRoofId: currentRoof.id, planeSize: currentRoof.length, actualSize: currentRoof.length }, + }) + let hip2 = new QLine([currentRoof.x2, currentRoof.y2, wallMidX, wallMidY], { + fontSize: roof.fontSize, + stroke: 'red', + strokeWidth: 1, + name: 'hipLine', + attributes: { roofId: roof.id, currentRoofId: currentRoof.id, planeSize: currentRoof.length, actualSize: currentRoof.length }, + }) + canvas?.add(hip1) + canvas?.add(hip2) + } if (hipLines.length > 0) { hipLines.forEach((hip) => { - const diffX = hip.x1 - wallMidX - const diffY = hip.y1 - wallMidY - console.log('diffX : ', diffX, ' diffY : ', diffY) - hip.set({ - x1: hip.x1, - y1: hip.y1, - x2: wallMidX, - y2: wallMidY, - }) + canvas?.remove(hip) }) } } -export const changeAllHipAndGableRoof = (polygon, offset, canvas) => { - const roof = polygon.filter((p) => p.name === 'roof')[0] // 지붕 - const roofLines = roof.lines // 지붕의 라인 - const ridges = roof.ridges // 마루의 라인 - const hips = roof.hips // 추녀마루의 라인 - - console.log('roofLines : ', roofLines) - - ridges.forEach((ridge) => { - let ridgeHip1 = hips.filter((hip) => hip.x2 === ridge.x1 && hip.y2 === ridge.y1) - let ridgeHip2 = hips.filter((hip) => hip.x2 === ridge.x2 && hip.y2 === ridge.y2) - let gableLines = [] - if (ridgeHip1.length > 1) { - let x1 = ridgeHip1[0].x1, - y1 = ridgeHip1[0].y1, - x2 = ridgeHip1[1].x1, - y2 = ridgeHip1[1].y1 - roofLines.filter((roofLine) => { - if ( - (roofLine.x1 === x1 && roofLine.y1 === y1 && roofLine.x2 === x2 && roofLine.y2 === y2) || - (roofLine.x1 === x2 && roofLine.y1 === y2 && roofLine.x2 === x1 && roofLine.y2 === y1) - ) { - gableLines.push(setHipAndGableRoof(roof, ridge, ridgeHip1[0], ridgeHip1[1], offset, canvas)) - } - }) - } - if (ridgeHip2.length > 1) { - let x1 = ridgeHip2[0].x1, - y1 = ridgeHip2[0].y1, - x2 = ridgeHip2[1].x1, - y2 = ridgeHip2[1].y1 - roofLines.filter((roofLine) => { - if ( - (roofLine.x1 === x1 && roofLine.y1 === y1 && roofLine.x2 === x2 && roofLine.y2 === y2) || - (roofLine.x1 === x2 && roofLine.y1 === y2 && roofLine.x2 === x1 && roofLine.y2 === y1) - ) { - gableLines.push(setHipAndGableRoof(roof, ridge, ridgeHip2[0], ridgeHip2[1], offset, canvas)) - } - }) - } - gableLines.forEach((gableLine) => { - roof.innerLines.push(gableLine) - }) - }) - - // splitPolygonWithLines(roof) -} - /** * 모임지붕 -> 팔작지붕 변경 * @param roof @@ -2860,7 +2908,7 @@ const reDrawPolygon = (polygon, canvas) => { let point = [] lines.forEach((line) => point.push({ x: line.x1, y: line.y1 })) - console.log('point : ', point) + canvas?.remove(polygon) const newPolygon = new QPolygon(point, { id: polygon.id, @@ -2877,14 +2925,17 @@ const reDrawPolygon = (polygon, canvas) => { newLines.forEach((line, index) => { lines.forEach((l, i) => { - if (index === i) { + if (line.x1 === l.x1 && line.y1 === l.y1) { line.id = l.id line.attributes = l.attributes } }) }) + canvas?.add(newPolygon) - canvas?.remove(polygon) + canvas?.renderAll() + + return newPolygon } function arePointsEqual(point1, point2) {