diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 111aa7e9..72035264 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -841,6 +841,8 @@ export function useModuleBasicSetting(tabNum) { const flowLines = getFlowLines(moduleSetupSurface, height) //육지붕이 아닐때만 넣는다 육지붕일땐 클릭 이벤트에 별도로 넣어놓음 + // let startPoint = flowLines.bottom + let startPoint = flowLines.bottom const moduleArray = [] @@ -859,69 +861,76 @@ export function useModuleBasicSetting(tabNum) { startPoint = { ...startPoint, y1: startPoint.y1 - heightMargin } } } - } else { - const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측 - const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측 - const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단 + } + //밑에가 평면이면 좌측으로 붙여서 배치 + if (flowLines.bottom.type === 'flat' && flowLines.left.type === 'curve') { + startPoint = flowLines.left + } - let totalLeftEndPoint = maxLeftEndPoint - startPoint.x1 - let totalTopEndPoint = maxTopEndPoint - startPoint.y1 - let totalWidth = Math.ceil(Math.abs(maxRightEndPoint - maxLeftEndPoint) / width) - let diffLeftEndPoint = Math.abs(totalLeftEndPoint / width) - let diffTopEndPoint = Math.abs(totalTopEndPoint / height) - let startColPoint = Math.abs(width * Math.ceil(diffLeftEndPoint) - startPoint.x1) - let tempMaxWidth = isMaxSetup ? width / 2 : width //최대배치인지 확인하려고 넣음 - if (isMaxSetup) totalWidth = totalWidth * 2 //최대배치시 2배로 늘려서 반씩 검사하기위함 + const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측 + const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측 + const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단 - for (let j = 0; j < diffTopEndPoint; j++) { - bottomMargin = j === 0 ? 0 : intvVer * j - for (let i = 0; i <= totalWidth; i++) { - leftMargin = i === 0 ? 0 : intvHor * i - chidoriLength = 0 - if (isChidori && !isMaxSetup) { - chidoriLength = j % 2 === 0 ? 0 : width / 2 - intvHor - } + let totalLeftEndPoint = maxLeftEndPoint - startPoint.x1 + let totalTopEndPoint = maxTopEndPoint - startPoint.y1 + let totalWidth = Math.ceil(Math.abs(maxRightEndPoint - maxLeftEndPoint) / width) + let diffLeftEndPoint = Math.abs(totalLeftEndPoint / width) + let diffTopEndPoint = Math.abs(totalTopEndPoint / height) + let startColPoint = Math.abs(width * Math.ceil(diffLeftEndPoint) - startPoint.x1) + let tempMaxWidth = isMaxSetup ? width / 2 : width //최대배치인지 확인하려고 넣음 + if (isMaxSetup) totalWidth = totalWidth * 2 //최대배치시 2배로 늘려서 반씩 검사하기위함 - square = [ - [startColPoint + tempMaxWidth * i - chidoriLength + leftMargin, startPoint.y1 - height * j - bottomMargin], - [startColPoint + tempMaxWidth * i + width - chidoriLength + leftMargin, startPoint.y1 - height * j - bottomMargin], - [startColPoint + tempMaxWidth * i + width - chidoriLength + leftMargin, startPoint.y1 - height * j - height - bottomMargin], - [startColPoint + tempMaxWidth * i - chidoriLength + leftMargin, startPoint.y1 - height * j - height - bottomMargin], - [startColPoint + tempMaxWidth * i - chidoriLength + leftMargin, startPoint.y1 - height * j - bottomMargin], - ] + for (let j = 0; j < diffTopEndPoint; j++) { + bottomMargin = j === 0 ? 0 : intvVer * j + for (let i = 0; i <= totalWidth; i++) { + leftMargin = i === 0 ? 0 : intvHor * i + chidoriLength = 0 + if (isChidori && !isMaxSetup) { + chidoriLength = j % 2 === 0 ? 0 : width / 2 - intvHor + } - let squarePolygon = turf.polygon([square]) - let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) - let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) + square = [ + [startColPoint + tempMaxWidth * i - chidoriLength + leftMargin, startPoint.y1 - height * j - bottomMargin], + [startColPoint + tempMaxWidth * i + width - chidoriLength + leftMargin, startPoint.y1 - height * j - bottomMargin], + [startColPoint + tempMaxWidth * i + width - chidoriLength + leftMargin, startPoint.y1 - height * j - height - bottomMargin], + [startColPoint + tempMaxWidth * i - chidoriLength + leftMargin, startPoint.y1 - height * j - height - bottomMargin], + [startColPoint + tempMaxWidth * i - chidoriLength + leftMargin, startPoint.y1 - height * j - bottomMargin], + ] - moduleOptions = { ...moduleOptions, fill: module.color, surfaceId: moduleSetupSurface.id, moduleInfo: module } - let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon }) + let squarePolygon = turf.polygon([square]) + let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) + let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) - let disjointFromTrestle = checkModuleDisjointSurface(squarePolygon, polygonToTurfPolygon(moduleSetupSurface, true)) - let isDisjoint = checkModuleDisjointObjects(squarePolygon, containsBatchObjects) + moduleOptions = { ...moduleOptions, fill: module.color, surfaceId: moduleSetupSurface.id, moduleInfo: module } + let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon }) - if (disjointFromTrestle && isDisjoint) { - if (index > 0) { - setupModule.forEach((item) => { - const isOverlap = item.some((item2) => turf.booleanOverlap(squarePolygon, polygonToTurfPolygon(item2, true))) - if (!isOverlap) { - canvas?.add(tempModule) - moduleSetupArray.push(tempModule) - moduleArray.push(tempModule) - } - }) - } else { - //최초 한번은 그냥 그린다 - //겹치는지 확인해서 포함된 모듈만 그린다 - canvas?.add(tempModule) - moduleSetupArray.push(tempModule) - moduleArray.push(tempModule) - } + let disjointFromTrestle = checkModuleDisjointSurface(squarePolygon, polygonToTurfPolygon(moduleSetupSurface, true)) + let isDisjoint = checkModuleDisjointObjects(squarePolygon, containsBatchObjects) + + if (disjointFromTrestle && isDisjoint) { + if (index > 0) { + setupModule.forEach((item) => { + const isOverlap = item.some((item2) => turf.booleanOverlap(squarePolygon, polygonToTurfPolygon(item2, true))) + if (!isOverlap) { + canvas?.add(tempModule) + moduleSetupArray.push(tempModule) + moduleArray.push(tempModule) + canvas.renderAll() + } + }) } else { - //디버깅용 - tempModule.set({ fill: 'rgba(255,190,41, 0.4)', stroke: 'black', strokeWidth: 1 }) + //최초 한번은 그냥 그린다 + //겹치는지 확인해서 포함된 모듈만 그린다 canvas?.add(tempModule) + moduleSetupArray.push(tempModule) + moduleArray.push(tempModule) + canvas.renderAll() } + } else { + //디버깅용 + // tempModule.set({ fill: 'rgba(255,190,41, 0.4)', stroke: 'black', strokeWidth: 1 }) + // canvas?.add(tempModule) + // canvas.renderAll() } } } @@ -965,6 +974,12 @@ export function useModuleBasicSetting(tabNum) { } } + console.log('flowLines.top', flowLines.top) + + if (flowLines.left.type === 'flat') { + startPoint = flowLines.top + } + const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측 const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단 const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //최하단 @@ -1013,6 +1028,7 @@ export function useModuleBasicSetting(tabNum) { canvas?.add(tempModule) moduleSetupArray.push(tempModule) moduleArray.push(tempModule) + canvas.renderAll() } }) } else { @@ -1021,11 +1037,13 @@ export function useModuleBasicSetting(tabNum) { canvas?.add(tempModule) moduleSetupArray.push(tempModule) moduleArray.push(tempModule) + canvas.renderAll() } } else { //디버깅용 - tempModule.set({ fill: 'rgba(255,190,41, 0.4)', stroke: 'black', strokeWidth: 1 }) - canvas?.add(tempModule) + // tempModule.set({ fill: 'rgba(255,190,41, 0.4)', stroke: 'black', strokeWidth: 1 }) + // canvas?.add(tempModule) + // canvas.renderAll() } } } @@ -1129,6 +1147,7 @@ export function useModuleBasicSetting(tabNum) { canvas?.add(tempModule) moduleSetupArray.push(tempModule) moduleArray.push(tempModule) + canvas.renderAll() } }) } else { @@ -1137,11 +1156,13 @@ export function useModuleBasicSetting(tabNum) { canvas?.add(tempModule) moduleSetupArray.push(tempModule) moduleArray.push(tempModule) + canvas.renderAll() } } else { //디버깅용 - tempModule.set({ fill: 'rgba(255,190,41, 0.4)', stroke: 'black', strokeWidth: 1 }) - canvas?.add(tempModule) + // tempModule.set({ fill: 'rgba(255,190,41, 0.4)', stroke: 'black', strokeWidth: 1 }) + // canvas?.add(tempModule) + // canvas.renderAll() } } } @@ -1232,6 +1253,7 @@ export function useModuleBasicSetting(tabNum) { canvas?.add(tempModule) moduleSetupArray.push(tempModule) moduleArray.push(tempModule) + canvas.renderAll() } }) } else { @@ -1240,11 +1262,13 @@ export function useModuleBasicSetting(tabNum) { canvas?.add(tempModule) moduleSetupArray.push(tempModule) moduleArray.push(tempModule) + canvas.renderAll() } } else { //디버깅용 - tempModule.set({ fill: 'rgba(255,190,41, 0.4)', stroke: 'black', strokeWidth: 1 }) - canvas?.add(tempModule) + // tempModule.set({ fill: 'rgba(255,190,41, 0.4)', stroke: 'black', strokeWidth: 1 }) + // canvas?.add(tempModule) + // canvas.renderAll() } } } diff --git a/src/hooks/roofcover/useAuxiliaryDrawing.js b/src/hooks/roofcover/useAuxiliaryDrawing.js index 4997bdf8..7cacdd03 100644 --- a/src/hooks/roofcover/useAuxiliaryDrawing.js +++ b/src/hooks/roofcover/useAuxiliaryDrawing.js @@ -24,7 +24,7 @@ import { calculateAngle, isSamePoint } from '@/util/qpolygon-utils' import { POLYGON_TYPE } from '@/common/common' // 보조선 작성 -export function useAuxiliaryDrawing(id) { +export function useAuxiliaryDrawing(id, isUseEffect = true) { const canvas = useRecoilValue(canvasState) const { addCanvasMouseEventListener, addDocumentEventListener, removeMouseLine, initEvent } = useEvent() // const { addCanvasMouseEventListener, addDocumentEventListener, removeMouseLine, initEvent } = useContext(EventContext) @@ -654,6 +654,8 @@ export function useAuxiliaryDrawing(id) { selectable: true, name: 'auxiliaryLine', isFixed: true, + attributes: { ...line1.attributes }, + parentId: line1.parentId, }, ) lineHistory.current.push(newLine) @@ -674,6 +676,8 @@ export function useAuxiliaryDrawing(id) { selectable: false, name: 'auxiliaryLine', isFixed: true, + attributes: { ...line1.attributes }, + parentId: line1.parentId, }) lineHistory.current.push(newLine) lineHistory.current = lineHistory.current.filter((history) => history !== line1) @@ -685,6 +689,8 @@ export function useAuxiliaryDrawing(id) { selectable: false, name: 'auxiliaryLine', isFixed: true, + attributes: { ...line1.attributes }, + parentId: line1.parentId, }) lineHistory.current.push(newLine) lineHistory.current = lineHistory.current.filter((history) => history !== line1) @@ -724,6 +730,8 @@ export function useAuxiliaryDrawing(id) { selectable: true, name: 'auxiliaryLine', isFixed: true, + attributes: { ...line1.attributes }, + parentId: line1.parentId, intersectionPoint, }) } else { @@ -733,6 +741,8 @@ export function useAuxiliaryDrawing(id) { selectable: true, name: 'auxiliaryLine', isFixed: true, + attributes: { ...line1.attributes }, + parentId: line1.parentId, intersectionPoint, }) } @@ -825,7 +835,7 @@ export function useAuxiliaryDrawing(id) { //lineHistory.current에 있는 선들 중 startPoint와 endPoint가 겹치는 line은 제거 // 겹치는 선 하나는 canvas에서 제거한다. - const tempLines = [...lineHistory.current] + const tempLines = canvas.getObjects().filter((obj) => obj.name === 'auxiliaryLine' && !obj.isAuxiliaryFixed) lineHistory.current = [] tempLines.forEach((line) => { if ( @@ -842,7 +852,7 @@ export function useAuxiliaryDrawing(id) { lineHistory.current.push(line) }) - const innerLines = lineHistory.current + const innerLines = lineHistory.current.filter((line) => line.name === 'auxiliaryLine' && line.visible) roofBases.forEach((roofBase) => { const tempPolygonPoints = [...roofBase.points].map((obj) => { @@ -865,6 +875,7 @@ export function useAuxiliaryDrawing(id) { actualSize: line.attributes?.actualSize ?? 0, planeSize: line.getLength(), } + line.isAuxiliaryFixed = true return true } }) diff --git a/src/hooks/useContextMenu.js b/src/hooks/useContextMenu.js index 38cdedc1..184a3aea 100644 --- a/src/hooks/useContextMenu.js +++ b/src/hooks/useContextMenu.js @@ -180,6 +180,12 @@ export function useContextMenu() { fn: () => { if (!currentObject) return const roof = canvas.getObjects().filter((obj) => obj.id === currentObject.attributes.roofId)[0] + if (!roof) { + // 아직 innerLines로 세팅이 안되어있는 line인 경우 제거 + canvas.remove(currentObject) + canvas.discardActiveObject() + return + } const innerLines = roof.innerLines?.filter((line) => currentObject.id !== line.id) roof.innerLines = [...innerLines] canvas.remove(currentObject) @@ -221,6 +227,11 @@ export function useContextMenu() { name: 'auxiliaryLine', attributes: { ...currentObject.attributes }, }) + + if (!currentObject.attributes.roofId) { + return + } + canvas .getObjects() .filter((obj) => obj.id === currentObject.attributes.roofId)[0] @@ -235,11 +246,21 @@ export function useContextMenu() { swalFire({ text: '지붕을 선택해주세요.' }) return } - const innerLines = canvas.getObjects().filter((obj) => obj.id === currentObject.attributes.roofId)[0].innerLines - innerLines.forEach((line) => { + const innerLines = canvas.getObjects().filter((obj) => obj.id === currentObject.attributes.roofId)[0]?.innerLines + if (innerLines) { + innerLines.forEach((line) => { + canvas.remove(line) + }) + innerLines.length = 0 + } + + // 확정되지 않은 보조선 + const notFixedAuxiliaryLines = canvas.getObjects().filter((obj) => obj.name === 'auxiliaryLine' && !obj.isAuxiliaryFixed) + + notFixedAuxiliaryLines.forEach((line) => { canvas.remove(line) }) - innerLines.length = 0 + canvas.renderAll() }, }, diff --git a/src/store/localeAtom.js b/src/store/localeAtom.js index 0f20fa87..0564e633 100644 --- a/src/store/localeAtom.js +++ b/src/store/localeAtom.js @@ -2,7 +2,7 @@ import { atom } from 'recoil' export const globalLocaleStore = atom({ key: 'globalLocaleState', - default: 'ko', + default: 'ja', }) export const appMessageStore = atom({