모듈 열.단 삭제기능 구현

This commit is contained in:
김민식 2024-12-27 16:34:42 +09:00
parent f56e5ca4b0
commit f08e1fd4ff
2 changed files with 163 additions and 148 deletions

View File

@ -1,11 +1,12 @@
import { BATCH_TYPE, POLYGON_TYPE } from '@/common/common'
import { canvasState } from '@/store/canvasAtom'
import { isOverlap, polygonToTurfPolygon } from '@/util/canvas-util'
import { isOverlap, polygonToTurfPolygon, rectToPolygon } from '@/util/canvas-util'
import { useRecoilValue } from 'recoil'
import { v4 as uuidv4 } from 'uuid'
import * as turf from '@turf/turf'
import { useSwal } from '../useSwal'
import { QPolygon } from '@/components/fabric/QPolygon'
import { useModuleBasicSetting } from './useModuleBasicSetting'
export const MODULE_REMOVE_TYPE = {
LEFT: 'left',
@ -20,6 +21,7 @@ export const MODULE_REMOVE_TYPE = {
export function useModule() {
const canvas = useRecoilValue(canvasState)
const { swalFire } = useSwal()
const { checkModuleDisjointObjects } = useModuleBasicSetting()
const moduleMove = (length, direction) => {
const checkModuleDisjointSurface = (squarePolygon, turfModuleSetupSurface) => {
@ -38,6 +40,8 @@ export function useModule() {
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === selectedModules[0].surfaceId)[0]
const isOverlapArray = []
const isInSurfaceArray = []
const isOverlapObjects = []
const objects = getObjects()
if (selectedModules) {
canvas.remove(...selectedModules)
@ -73,16 +77,28 @@ export function useModule() {
//나갔는지 확인하는 로직
const isInSurface = turf.booleanContains(turfModuleSetupSurface, turfModule) || turf.booleanWithin(turfModule, turfModuleSetupSurface)
isInSurfaceArray.push(isInSurface)
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
})
const isNotOverlap = isOverlapArray.some((isOverlap) => isOverlap) // true면 겹침
const isNotOutSurface = isInSurfaceArray.every((isOutSurface) => isOutSurface) //false면 밖으로 나감
//안겹치고 안나갔으면 이동시킨다 아니면 원래 위치로 돌려놓는다
if (isNotOverlap || !isNotOutSurface) {
selectedModules.forEach((module) => {
module.set({ ...module, left: module.originCoords.left, top: module.originCoords.top })
module.setCoords()
if (isNotOverlap || !isNotOutSurface || isOverlapObjects.some((isOverlap) => isOverlap)) {
swalFire({
title: isNotOverlap
? '겹치는 모듈이 있습니다.'
: isOverlapObjects.some((isOverlap) => isOverlap)
? '모듈이 오브젝트와 겹칩니다.'
: '영역 밖',
icon: 'error',
type: 'confirm',
confirmFn: () => {
selectedModules.forEach((module) => {
module.set({ ...module, left: module.originCoords.left, top: module.originCoords.top })
module.setCoords()
})
},
})
}
@ -95,11 +111,12 @@ export function useModule() {
if (canvas.getActiveObjects().length === 0) return
const activeModuleIds = canvas.getActiveObjects().map((obj) => obj.id)
const modules = canvas.getObjects().filter((obj) => activeModuleIds.includes(obj.id))
const objects = getObjects()
const otherModules = canvas.getObjects().filter((obj) => obj.surfaceId === modules[0].surfaceId && obj.name === POLYGON_TYPE.MODULE)
const moduleSetupSurface = canvas
.getObjects()
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === modules[0].surfaceId)[0]
let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
canvas.discardActiveObject() //선택해제
modules.forEach((module) => {
const { top, left } = getPosotion(module, direction, length, true)
@ -109,20 +126,28 @@ export function useModule() {
rect.setCoords()
canvas.renderAll()
// const isOverlapOtherModules = otherModules.some((otherModule) => rect.intersectsWithObject(otherModule))
const isOverlapOtherModules = otherModules.some(
(otherModule) =>
turf.booleanOverlap(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(otherModule, true)) ||
turf.booleanWithin(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(otherModule, true)),
isOverlapOtherModules.push(
otherModules.some(
(otherModule) =>
turf.booleanOverlap(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(otherModule, true)) ||
turf.booleanWithin(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(otherModule, true)),
),
)
const isOutsideSurface =
!turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(rect, true)) ||
!turf.booleanWithin(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(moduleSetupSurface, true))
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(rect, true), objects))
if (isOverlapOtherModules || isOutsideSurface) {
isOutsideSurface.push(
!turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(rect, true)) ||
!turf.booleanWithin(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(moduleSetupSurface, true)),
)
if (
isOverlapOtherModules.some((isOverlap) => isOverlap) ||
isOutsideSurface.some((isOutside) => isOutside) ||
isOverlapObjects.some((isOverlap) => isOverlap)
) {
swalFire({
title: isOverlapOtherModules ? '겹치는 모듈이 있습니다.' : '영역 밖',
title: isOverlapOtherModules ? '겹치는 모듈이 있습니다.' : isOutsideSurface ? '모듈이 오브젝트와 겹칩니다.' : '영역 밖',
icon: 'error',
type: 'confirm',
confirmFn: () => {
@ -133,6 +158,7 @@ export function useModule() {
}
})
}
const moduleMultiMove = (type, length, direction) => {
if (canvas.getActiveObjects().length === 0) return
if (canvas.getActiveObjects().length > 1) {
@ -148,6 +174,8 @@ export function useModule() {
const modules = type === 'row' ? getRowModules(activeModule) : getColumnModules(activeModule)
const otherModules = getOtherModules(modules)
const objects = getObjects()
console.log('🚀 ~ moduleMultiMove ~ objects:', objects)
const moduleSetupSurface = canvas
.getObjects()
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
@ -175,13 +203,7 @@ export function useModule() {
}
if (objects.length > 0) {
isOverlapObjects.push(
objects.some(
(object) =>
turf.booleanOverlap(polygonToTurfPolygon(module, true), polygonToTurfPolygon(object, true)) ||
turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(object, true)),
),
)
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
}
isOutsideSurface.push(
@ -196,7 +218,11 @@ export function useModule() {
isOutsideSurface.some((isOutside) => isOutside)
) {
swalFire({
title: isOverlapOtherModules.some((isOverlap) => isOverlap) ? '겹치는 모듈이 있습니다.' : '영역 밖',
title: isOverlapOtherModules.some((isOverlap) => isOverlap)
? '겹치는 모듈이 있습니다.'
: isOverlapObjects.some((isOverlap) => isOverlap)
? '모듈이 오브젝트와 겹칩니다.'
: '영역 밖',
icon: 'error',
type: 'confirm',
confirmFn: () => {
@ -232,9 +258,9 @@ export function useModule() {
let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
modules.forEach((module) => {
const { top, left } = getPosotion(module, direction, length, true)
const { top, left } = getPosotion(module, direction, length, false)
const moduleOptions = { ...module, left, top, id: uuidv4() }
const rect = new QPolygon(module.points, moduleOptions)
const rect = new QPolygon(module.getCurrentPoints(), moduleOptions)
canvas.add(rect)
copyRects.push(rect)
module.setCoords()
@ -250,13 +276,7 @@ export function useModule() {
}
if (objects.length > 0) {
isOverlapObjects.push(
objects.some(
(object) =>
turf.booleanOverlap(polygonToTurfPolygon(module, true), polygonToTurfPolygon(object, true)) ||
turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(object, true)),
),
)
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
}
isOutsideSurface.push(
@ -271,7 +291,11 @@ export function useModule() {
isOutsideSurface.some((isOutside) => isOutside)
) {
swalFire({
title: isOverlapOtherModules.some((isOverlap) => isOverlap) ? '겹치는 모듈이 있습니다.' : '영역 밖',
title: isOverlapOtherModules.some((isOverlap) => isOverlap)
? '겹치는 모듈이 있습니다.'
: isOverlapObjects.some((isOverlap) => isOverlap)
? '모듈이 오브젝트와 겹칩니다.'
: '영역 밖',
icon: 'error',
type: 'confirm',
confirmFn: () => {
@ -284,35 +308,11 @@ export function useModule() {
}
}
const getIsOverlapOtherModules = (module, otherModules) => {
return otherModules.some(
(otherModule) =>
turf.booleanOverlap(polygonToTurfPolygon(module, true), polygonToTurfPolygon(otherModule, true)) ||
turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(otherModule, true)),
)
}
const getIsOverlapObjects = (module, objects) => {
return objects.some(
(object) =>
turf.booleanOverlap(polygonToTurfPolygon(module, true), polygonToTurfPolygon(object, true)) ||
turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(object, true)),
)
}
const getIsOutsideSurface = (module, moduleSetupSurface) => {
return (
!turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(module, true)) ||
!turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(moduleSetupSurface, true))
)
}
const moduleColumnRemove = (type) => {
const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
const columnModules = getColumnModules(activeModule)
const otherModules = getOtherModules(columnModules)
const objects = getObjects()
console.log('🚀 ~ moduleColumnRemove ~ objects:', objects)
let targetModules = []
const rightModules = otherModules.filter((module) => activeModule.left < module.left).sort((a, b) => a.left - b.left)
const leftModules = otherModules.filter((module) => activeModule.left > module.left).sort((a, b) => b.left - a.left)
@ -321,19 +321,11 @@ export function useModule() {
.getObjects()
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
console.log(
'🚀 ~ moduleColumnRemove ~ isOverlapOtherModules, isOverlapObjects, isOutsideSurface:',
isOverlapOtherModules,
isOverlapObjects,
isOutsideSurface,
)
canvas.discardActiveObject()
canvas.remove(...columnModules)
canvas.renderAll()
if (type === MODULE_REMOVE_TYPE.LEFT) {
console.log('🚀 ~ moduleColumnRemove ~ rightModules:', rightModules)
rightModules.forEach((module) => {
module.originPos = {
left: module.left,
@ -344,7 +336,7 @@ export function useModule() {
module.setCoords()
canvas.renderAll()
isOverlapOtherModules.push(getIsOverlapOtherModules(module, leftModules))
isOverlapObjects.push(getIsOverlapObjects(module, objects))
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
})
targetModules = rightModules
@ -359,7 +351,7 @@ export function useModule() {
module.setCoords()
canvas.renderAll()
isOverlapOtherModules.push(getIsOverlapOtherModules(module, rightModules))
isOverlapObjects.push(getIsOverlapObjects(module, objects))
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
})
targetModules = leftModules
@ -394,19 +386,12 @@ export function useModule() {
sideModules.filter((m) => m.id !== module.id),
),
)
isOverlapObjects.push(getIsOverlapObjects(module, objects))
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
})
targetModules = sideModules
}
console.log('🚀 ~ sideModules.forEach ~ objects:', objects)
console.log(
'🚀 ~ moduleColumnRemove ~ isOverlapOtherModules, isOverlapObjects, isOutsideSurface:',
isOverlapOtherModules,
isOverlapObjects,
isOutsideSurface,
)
if (
(isOverlapOtherModules.some((isOverlap) => isOverlap) ||
isOverlapObjects.some((isOverlap) => isOverlap) ||
@ -414,9 +399,10 @@ export function useModule() {
type !== MODULE_REMOVE_TYPE.NONE
) {
swalFire({
title:
isOverlapOtherModules.some((isOverlap) => isOverlap) || isOverlapObjects.some((isOverlap) => isOverlap)
? '겹치는 모듈이 있습니다.'
title: isOverlapOtherModules.some((isOverlap) => isOverlap)
? '겹치는 모듈이 있습니다.'
: isOverlapObjects.some((isOverlap) => isOverlap)
? '모듈이 오브젝트와 겹칩니다.'
: '영역 밖',
icon: 'error',
type: 'confirm',
@ -426,10 +412,10 @@ export function useModule() {
module.set({ top: module.originPos.top, left: module.originPos.left })
module.setCoords()
})
canvas.renderAll()
},
})
}
canvas.renderAll()
}
const moduleRowRemove = (type) => {
@ -461,7 +447,7 @@ export function useModule() {
module.setCoords()
canvas.renderAll()
isOverlapOtherModules.push(getIsOverlapOtherModules(module, topModules))
isOverlapObjects.push(getIsOverlapObjects(module, objects))
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
})
targetModules = bottomModules
@ -476,7 +462,7 @@ export function useModule() {
module.setCoords()
canvas.renderAll()
isOverlapOtherModules.push(getIsOverlapOtherModules(module, bottomModules))
isOverlapObjects.push(getIsOverlapObjects(module, objects))
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
})
targetModules = topModules
@ -512,7 +498,7 @@ export function useModule() {
sideModules.filter((m) => m.id !== module.id),
),
)
isOverlapObjects.push(getIsOverlapObjects(module, objects))
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
})
targetModules = sideModules
@ -525,9 +511,10 @@ export function useModule() {
type !== MODULE_REMOVE_TYPE.NONE
) {
swalFire({
title:
isOverlapOtherModules.some((isOverlap) => isOverlap) || isOverlapObjects.some((isOverlap) => isOverlap)
? '겹치는 모듈이 있습니다.'
title: isOverlapOtherModules.some((isOverlap) => isOverlap)
? '겹치는 모듈이 있습니다.'
: isOverlapObjects.some((isOverlap) => isOverlap)
? '모듈이 오브젝트와 겹칩니다.'
: '영역 밖',
icon: 'error',
type: 'confirm',
@ -537,10 +524,10 @@ export function useModule() {
module.set({ top: module.originPos.top, left: module.originPos.left })
module.setCoords()
})
canvas.renderAll()
},
})
}
canvas.renderAll()
}
const getRowModules = (target) => {
@ -559,7 +546,7 @@ export function useModule() {
top = Number(target.top) - Number(length)
top = hasMargin ? top - Number(target.height) : top
} else if (direction === 'down') {
top = Number(target.top) + Number(target.height) + Number(length)
top = Number(target.top) + Number(length)
top = hasMargin ? top + Number(target.height) : top
} else if (direction === 'left') {
left = Number(target.left) - Number(length)
@ -584,6 +571,29 @@ export function useModule() {
.filter((obj) => [BATCH_TYPE.OPENING, BATCH_TYPE.TRIANGLE_DORMER, BATCH_TYPE.PENTAGON_DORMER, BATCH_TYPE.SHADOW].includes(obj.name))
}
const getIsOverlapOtherModules = (module, otherModules) => {
return otherModules.some(
(otherModule) =>
turf.booleanOverlap(polygonToTurfPolygon(module, true), polygonToTurfPolygon(otherModule, true)) ||
turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(otherModule, true)),
)
}
const getIsOverlapObjects = (module, objects) => {
return !objects.some(
(object) =>
turf.booleanOverlap(polygonToTurfPolygon(module, true), polygonToTurfPolygon(object, true)) ||
turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(object, true)),
)
}
const getIsOutsideSurface = (module, moduleSetupSurface) => {
return (
!turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(module, true)) ||
!turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(moduleSetupSurface, true))
)
}
return {
moduleMove,
moduleMultiMove,

View File

@ -429,7 +429,8 @@ export function useModuleBasicSetting() {
dormerTurfPolygon = batchObjectGroupToTurfPolygon(object)
} else {
//개구, 그림자
dormerTurfPolygon = polygonToTurfPolygon(rectToPolygon(object))
object.set({ points: rectToPolygon(object) })
dormerTurfPolygon = polygonToTurfPolygon(object)
}
const intersection = turf.intersect(turf.featureCollection([dormerTurfPolygon, tempTurfModule])) //겹치는지 확인
@ -566,35 +567,35 @@ export function useModuleBasicSetting() {
return containsBatchObjects
}
/**
* 도머나 개구가 모듈에 걸치는지 확인하는 로직
* @param {*} squarePolygon
* @param {*} containsBatchObjects
* @returns
*/
const checkModuleDisjointObjects = (squarePolygon, containsBatchObjects) => {
let isDisjoint = false
if (containsBatchObjects.length > 0) {
let convertBatchObject
//도머가 있으면 적용되는 로직
isDisjoint = containsBatchObjects.every((batchObject) => {
if (batchObject.type === 'group') {
convertBatchObject = batchObjectGroupToTurfPolygon(batchObject)
} else {
convertBatchObject = polygonToTurfPolygon(batchObject)
}
/**
* 도머가 여러개일수있으므로 겹치는게 있다면...
* 안겹치는지 확인하는 로직이라 안겹치면 true를 반환
*/
return turf.booleanDisjoint(squarePolygon, convertBatchObject)
})
} else {
isDisjoint = true
}
return isDisjoint
}
// /**
// * 도머나 개구가 모듈에 걸치는지 확인하는 로직
// * @param {*} squarePolygon
// * @param {*} containsBatchObjects
// * @returns
// */
// const checkModuleDisjointObjects = (squarePolygon, containsBatchObjects) => {
// let isDisjoint = false
//
// if (containsBatchObjects.length > 0) {
// let convertBatchObject
// //도머가 있으면 적용되는 로직
// isDisjoint = containsBatchObjects.every((batchObject) => {
// if (batchObject.type === 'group') {
// convertBatchObject = batchObjectGroupToTurfPolygon(batchObject)
// } else {
// convertBatchObject = polygonToTurfPolygon(batchObject)
// }
// /**
// * 도머가 여러개일수있으므로 겹치는게 있다면...
// * 안겹치는지 확인하는 로직이라 안겹치면 true를 반환
// */
// return turf.booleanDisjoint(squarePolygon, convertBatchObject)
// })
// } else {
// isDisjoint = true
// }
// return isDisjoint
// }
/**
* 배치면 안에 있는지 확인
@ -1997,36 +1998,6 @@ export function useModuleBasicSetting() {
return containsBatchObjects
}
/**
* 도머나 개구가 모듈에 걸치는지 확인하는 로직
* @param {*} squarePolygon
* @param {*} containsBatchObjects
* @returns
*/
const checkModuleDisjointObjects = (squarePolygon, containsBatchObjects) => {
let isDisjoint = false
if (containsBatchObjects.length > 0) {
let convertBatchObject
//도머가 있으면 적용되는 로직
isDisjoint = containsBatchObjects.every((batchObject) => {
if (batchObject.type === 'group') {
convertBatchObject = batchObjectGroupToTurfPolygon(batchObject)
} else {
convertBatchObject = polygonToTurfPolygon(batchObject)
}
/**
* 도머가 여러개일수있으므로 겹치는게 있다면...
* 안겹치는지 확인하는 로직이라 안겹치면 true를 반환
*/
return turf.booleanDisjoint(squarePolygon, convertBatchObject)
})
} else {
isDisjoint = true
}
return isDisjoint
}
/**
* 배치면 안에 있는지 확인
* @param {*} squarePolygon
@ -2287,6 +2258,39 @@ export function useModuleBasicSetting() {
//드래그 하기위해 기능 활성화
}
/**
* 도머나 개구가 모듈에 걸치는지 확인하는 로직
* @param {*} squarePolygon
* @param {*} containsBatchObjects
* @returns
*/
const checkModuleDisjointObjects = (squarePolygon, containsBatchObjects) => {
let isDisjoint = false
if (containsBatchObjects.length > 0) {
let convertBatchObject
//도머가 있으면 적용되는 로직
isDisjoint = containsBatchObjects.every((batchObject) => {
if (batchObject.type === 'group') {
convertBatchObject = batchObjectGroupToTurfPolygon(batchObject)
} else {
if (!batchObject.points) {
batchObject.set({ points: rectToPolygon(batchObject) })
}
convertBatchObject = polygonToTurfPolygon(batchObject)
}
/**
* 도머가 여러개일수있으므로 겹치는게 있다면...
* 안겹치는지 확인하는 로직이라 안겹치면 true를 반환
*/
return turf.booleanDisjoint(squarePolygon, convertBatchObject)
})
} else {
isDisjoint = true
}
return isDisjoint
}
return {
makeModuleInstArea,
manualModuleSetup,
@ -2294,5 +2298,6 @@ export function useModuleBasicSetting() {
restoreModuleInstArea,
manualFlatroofModuleSetup,
autoFlatroofModuleSetup,
checkModuleDisjointObjects,
}
}