- {roofList.map((roof, index) => {
+ {currentRoofList.map((roof, index) => {
return (
@@ -136,6 +137,7 @@ export default function RoofAllocationSetting(props) {
showKey={'clCodeNm'}
sourceKey={'clCode'}
targetKey={roof.raft ? 'raft' : 'raftBaseCd'}
+ onChange={(e) => handleChangeRaft(e, index)}
/>
)}
diff --git a/src/components/sample/SampleReducer.jsx b/src/components/sample/SampleReducer.jsx
new file mode 100644
index 00000000..26150fea
--- /dev/null
+++ b/src/components/sample/SampleReducer.jsx
@@ -0,0 +1,115 @@
+import { Card, CardBody, Input, Tab, Tabs } from '@nextui-org/react'
+import { useEffect, useReducer } from 'react'
+
+const reducer = (prevState, nextState) => {
+ return { ...prevState, ...nextState }
+}
+
+const defaultData = {
+ commonData: 'common',
+ tabs: [
+ {
+ id: 1,
+ name: 'tab1',
+ range: 10,
+ maker: 'maker1',
+ law: 'law1',
+ basis: 'basis1',
+ },
+ {
+ id: 2,
+ name: 'tab2',
+ range: 20,
+ maker: 'maker2',
+ law: 'law2',
+ basis: 'basis2',
+ },
+ {
+ id: 3,
+ name: 'tab3',
+ range: 30,
+ maker: 'maker3',
+ law: 'law3',
+ basis: 'basis3',
+ },
+ {
+ id: 4,
+ name: 'tab4',
+ range: 40,
+ maker: 'maker4',
+ law: 'law4',
+ basis: 'basis4',
+ },
+ ],
+}
+
+export default function SampleReducer() {
+ const [sampleState, setSampleState] = useReducer(reducer, defaultData)
+
+ const handleChangeTabsData = (newTab) => {
+ const newTabs = sampleState.tabs.map((t) => {
+ if (t.id === newTab.id) {
+ return newTab
+ } else {
+ return t
+ }
+ })
+ setSampleState({ ...sampleState, tabs: newTabs })
+ }
+
+ useEffect(() => {
+ console.log('🚀 ~ SampleReducer ~ sampleState:', sampleState)
+ }, [sampleState])
+
+ return (
+ <>
+
공통: {sampleState.commonData}
+
+ >
+ )
+}
diff --git a/src/hooks/common/useRoofFn.js b/src/hooks/common/useRoofFn.js
index afe1c71e..eb932106 100644
--- a/src/hooks/common/useRoofFn.js
+++ b/src/hooks/common/useRoofFn.js
@@ -1,11 +1,13 @@
import { useRecoilValue } from 'recoil'
-import { canvasState } from '@/store/canvasAtom'
+import { canvasState, currentObjectState } from '@/store/canvasAtom'
import { selectedRoofMaterialSelector } from '@/store/settingAtom'
import { ROOF_MATERIAL_LAYOUT } from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting'
+import { POLYGON_TYPE } from '@/common/common'
export function useRoofFn() {
const canvas = useRecoilValue(canvasState)
const selectedRoofMaterial = useRecoilValue(selectedRoofMaterialSelector)
+ const currentObject = useRecoilValue(currentObjectState)
//면형상 선택 클릭시 지붕 패턴 입히기
function setSurfaceShapePattern(polygon, mode = 'onlyBorder', trestleMode = false, roofMaterial = selectedRoofMaterial) {
@@ -141,5 +143,22 @@ export function useRoofFn() {
polygon.roofMaterial = roofMaterial
polygon.canvas?.renderAll()
}
- return { setSurfaceShapePattern }
+
+ function removeRoofMaterial(roof = currentObject) {
+ if (roof === null || roof.name !== POLYGON_TYPE.ROOF) {
+ return
+ }
+ roof.set('fill', null)
+ roof.roofMaterial = null
+ canvas?.renderAll()
+ }
+
+ function removeAllRoofMaterial() {
+ const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
+ roofBases.forEach((roofBase) => {
+ removeRoofMaterial(roofBase)
+ })
+ }
+
+ return { setSurfaceShapePattern, removeRoofMaterial, removeAllRoofMaterial }
}
diff --git a/src/hooks/module/useModule.js b/src/hooks/module/useModule.js
new file mode 100644
index 00000000..5e494412
--- /dev/null
+++ b/src/hooks/module/useModule.js
@@ -0,0 +1,833 @@
+import { BATCH_TYPE, POLYGON_TYPE } from '@/common/common'
+import { canvasState } from '@/store/canvasAtom'
+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',
+ RIGHT: 'right',
+ HORIZONTAL_SIDE: 'horizontalSide',
+ TOP: 'top',
+ BOTTOM: 'bottom',
+ VERTICAL_SIDE: 'verticalSide',
+ NONE: 'none',
+}
+
+export const MODULE_INSERT_TYPE = {
+ LEFT: 'left',
+ RIGHT: 'right',
+ TOP: 'up',
+ BOTTOM: 'down',
+}
+
+export function useModule() {
+ const canvas = useRecoilValue(canvasState)
+ const { swalFire } = useSwal()
+ const { checkModuleDisjointObjects } = useModuleBasicSetting()
+
+ const moduleMove = (length, direction) => {
+ const checkModuleDisjointSurface = (squarePolygon, turfModuleSetupSurface) => {
+ return turf.booleanContains(turfModuleSetupSurface, squarePolygon) || turf.booleanWithin(squarePolygon, turfModuleSetupSurface)
+ }
+
+ const selectedObj = canvas.getActiveObjects() //선택된 객체들을 가져옴
+ const selectedIds = selectedObj.map((obj) => obj.id) // selectedObj의 ID 추출
+
+ canvas.discardActiveObject() //선택해제
+
+ const isSetupModules = canvas.getObjects().filter((obj) => obj.name === 'module' && !selectedIds.includes(obj.id)) // selectedObj에 없는 객체만 필터링
+ const selectedModules = canvas.getObjects().filter((obj) => selectedIds.includes(obj.id) && obj.name === 'module') //선택했던 객체들만 가져옴
+ const setupSurface = canvas
+ .getObjects()
+ .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)
+ selectedModules.forEach((module) => {
+ module.set({
+ originCoords: {
+ left: module.left,
+ top: module.top,
+ },
+ })
+
+ if (direction === 'up') {
+ module.set({ ...module, top: module.top - Number(length) })
+ } else if (direction === 'down') {
+ module.set({ ...module, top: module.top + Number(length) })
+ } else if (direction === 'left') {
+ module.set({ ...module, left: module.left - Number(length) })
+ } else if (direction === 'right') {
+ module.set({ ...module, left: module.left + Number(length) })
+ }
+ module.setCoords()
+ canvas.renderAll()
+
+ //다른 모듈과 겹치는지 확인하는 로직
+ const isOverlap = isSetupModules.some((isSetupModule) =>
+ turf.booleanOverlap(polygonToTurfPolygon(module, true), polygonToTurfPolygon(isSetupModule, true)),
+ )
+ isOverlapArray.push(isOverlap)
+
+ const turfModuleSetupSurface = polygonToTurfPolygon(setupSurface, true)
+ const turfModule = polygonToTurfPolygon(module, true)
+
+ //나갔는지 확인하는 로직
+ 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 || 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()
+ })
+ },
+ })
+ }
+
+ canvas.add(...selectedModules)
+ canvas.renderAll()
+ }
+ }
+
+ const moduleCopy = (length, direction) => {
+ 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)
+ const moduleOptions = { ...module, left, top, id: uuidv4() }
+ const rect = new QPolygon(module.points, moduleOptions)
+ canvas.add(rect)
+ rect.setCoords()
+ canvas.renderAll()
+
+ isOverlapOtherModules.push(
+ otherModules.some(
+ (otherModule) =>
+ turf.booleanOverlap(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(otherModule, true)) ||
+ turf.booleanWithin(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(otherModule, true)),
+ ),
+ )
+
+ isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(rect, true), objects))
+
+ 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 ? '겹치는 모듈이 있습니다.' : isOutsideSurface ? '모듈이 오브젝트와 겹칩니다.' : '영역 밖',
+ icon: 'error',
+ type: 'confirm',
+ confirmFn: () => {
+ canvas.remove(rect)
+ canvas.renderAll()
+ },
+ })
+ }
+ })
+ }
+
+ const moduleMultiMove = (type, length, direction) => {
+ if (canvas.getActiveObjects().length === 0) return
+ if (canvas.getActiveObjects().length > 1) {
+ swalFire({
+ title: '여러 개의 모듈을 선택할 수 없습니다.',
+ icon: 'error',
+ type: 'alert',
+ })
+ canvas.discardActiveObject()
+ return
+ }
+ const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
+ 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]
+ let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
+
+ modules.forEach((module) => {
+ const { top, left } = getPosotion(module, direction, length, false)
+ module.originPos = {
+ top: module.top,
+ left: module.left,
+ }
+
+ module.set({ top, left })
+ module.setCoords()
+ canvas.renderAll()
+
+ if (otherModules.length > 0) {
+ isOverlapOtherModules.push(
+ otherModules.some(
+ (otherModule) =>
+ turf.booleanOverlap(polygonToTurfPolygon(module, true), polygonToTurfPolygon(otherModule, true)) ||
+ turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(otherModule, true)),
+ ),
+ )
+ }
+
+ if (objects.length > 0) {
+ isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
+ }
+
+ isOutsideSurface.push(
+ !turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(module, true)) ||
+ !turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(moduleSetupSurface, true)),
+ )
+ })
+
+ if (
+ isOverlapOtherModules.some((isOverlap) => isOverlap) ||
+ isOverlapObjects.some((isOverlap) => isOverlap) ||
+ isOutsideSurface.some((isOutside) => isOutside)
+ ) {
+ swalFire({
+ title: isOverlapOtherModules.some((isOverlap) => isOverlap)
+ ? '겹치는 모듈이 있습니다.'
+ : isOverlapObjects.some((isOverlap) => isOverlap)
+ ? '모듈이 오브젝트와 겹칩니다.'
+ : '영역 밖',
+ icon: 'error',
+ type: 'confirm',
+ confirmFn: () => {
+ modules.forEach((module) => {
+ module.set({ top: module.originPos.top, left: module.originPos.left })
+ module.setCoords()
+ })
+ canvas.renderAll()
+ },
+ })
+ }
+ }
+
+ const moduleMultiCopy = (type, length, direction) => {
+ if (canvas.getActiveObjects().length === 0) return
+ if (canvas.getActiveObjects().length > 1) {
+ swalFire({
+ title: '여러 개의 모듈을 선택할 수 없습니다.',
+ icon: 'error',
+ type: 'alert',
+ })
+ canvas.discardActiveObject()
+ return
+ }
+ const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
+ const modules = type === 'row' ? getRowModules(activeModule) : getColumnModules(activeModule)
+ const otherModules = canvas.getObjects().filter((obj) => obj.surfaceId === modules[0].surfaceId && obj.name === POLYGON_TYPE.MODULE)
+ const objects = getObjects()
+ const copyRects = []
+ const moduleSetupSurface = canvas
+ .getObjects()
+ .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === modules[0].surfaceId)[0]
+ let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
+ let moduleLength = 0
+ if (['up', 'down'].includes(direction)) {
+ moduleLength = Number(modules[modules.length - 1].top) + Number(modules[modules.length - 1].height) - Number(modules[0].top)
+ } else if (['left', 'right'].includes(direction)) {
+ moduleLength = Number(modules[modules.length - 1].left) + Number(modules[modules.length - 1].width) - Number(modules[0].left)
+ }
+
+ modules.forEach((module) => {
+ const { top, left } = getPosotion(module, direction, Number(length) + Number(moduleLength), false)
+ const moduleOptions = { ...module, left, top, id: uuidv4() }
+ const rect = new QPolygon(module.getCurrentPoints(), moduleOptions)
+ canvas.add(rect)
+ copyRects.push(rect)
+ module.setCoords()
+
+ if (otherModules.length > 0) {
+ isOverlapOtherModules.push(
+ otherModules.some(
+ (otherModule) =>
+ turf.booleanOverlap(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(otherModule, true)) ||
+ turf.booleanWithin(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(otherModule, true)),
+ ),
+ )
+ }
+
+ if (objects.length > 0) {
+ isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
+ }
+
+ isOutsideSurface.push(
+ !turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(rect, true)) ||
+ !turf.booleanWithin(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(moduleSetupSurface, true)),
+ )
+ })
+
+ if (
+ isOverlapOtherModules.some((isOverlap) => isOverlap) ||
+ isOverlapObjects.some((isOverlap) => isOverlap) ||
+ isOutsideSurface.some((isOutside) => isOutside)
+ ) {
+ swalFire({
+ title: isOverlapOtherModules.some((isOverlap) => isOverlap)
+ ? '겹치는 모듈이 있습니다.'
+ : isOverlapObjects.some((isOverlap) => isOverlap)
+ ? '모듈이 오브젝트와 겹칩니다.'
+ : '영역 밖',
+ icon: 'error',
+ type: 'confirm',
+ confirmFn: () => {
+ canvas.remove(...copyRects)
+ canvas.renderAll()
+ },
+ })
+ } else {
+ canvas.renderAll()
+ }
+ }
+
+ 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()
+ 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)
+ let width = -1
+ const moduleSetupSurface = canvas
+ .getObjects()
+ .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
+ let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
+ canvas.discardActiveObject()
+ canvas.remove(...columnModules)
+ canvas.renderAll()
+
+ if (type === MODULE_REMOVE_TYPE.LEFT) {
+ rightModules.forEach((module) => {
+ module.originPos = {
+ left: module.left,
+ top: module.top,
+ }
+ if (width === -1) width = module.left - activeModule.left
+ module.set({ left: module.left - width })
+ module.setCoords()
+ canvas.renderAll()
+ isOverlapOtherModules.push(getIsOverlapOtherModules(module, leftModules))
+ isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
+ isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
+ })
+ targetModules = rightModules
+ } else if (type === MODULE_REMOVE_TYPE.RIGHT) {
+ leftModules.forEach((module) => {
+ module.originPos = {
+ left: module.left,
+ top: module.top,
+ }
+ if (width === -1) width = activeModule.left - module.left
+ module.set({ left: module.left + width })
+ module.setCoords()
+ canvas.renderAll()
+ isOverlapOtherModules.push(getIsOverlapOtherModules(module, rightModules))
+ isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
+ isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
+ })
+ targetModules = leftModules
+ } else if (type === MODULE_REMOVE_TYPE.HORIZONTAL_SIDE) {
+ const sideModules = [...leftModules, ...rightModules]
+ leftModules.forEach((module) => {
+ module.originPos = {
+ left: module.left,
+ top: module.top,
+ }
+ if (width === -1) width = activeModule.left - module.left
+ module.set({ left: module.left + width / 2 })
+ module.setCoords()
+ canvas.renderAll()
+ })
+
+ rightModules.forEach((module) => {
+ module.originPos = {
+ left: module.left,
+ top: module.top,
+ }
+ if (width === -1) width = module.left - activeModule.left
+ module.set({ left: module.left - width / 2 })
+ module.setCoords()
+ canvas.renderAll()
+ })
+ canvas.renderAll()
+ sideModules.forEach((module) => {
+ isOverlapOtherModules.push(
+ getIsOverlapOtherModules(
+ module,
+ sideModules.filter((m) => m.id !== module.id),
+ ),
+ )
+ isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
+ isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
+ })
+
+ targetModules = sideModules
+ }
+ if (
+ (isOverlapOtherModules.some((isOverlap) => isOverlap) ||
+ isOverlapObjects.some((isOverlap) => isOverlap) ||
+ isOutsideSurface.some((isOutside) => isOutside)) &&
+ type !== MODULE_REMOVE_TYPE.NONE
+ ) {
+ swalFire({
+ title: isOverlapOtherModules.some((isOverlap) => isOverlap)
+ ? '겹치는 모듈이 있습니다.'
+ : isOverlapObjects.some((isOverlap) => isOverlap)
+ ? '모듈이 오브젝트와 겹칩니다.'
+ : '영역 밖',
+ icon: 'error',
+ type: 'confirm',
+ confirmFn: () => {
+ canvas.add(...columnModules)
+ targetModules.forEach((module) => {
+ module.set({ top: module.originPos.top, left: module.originPos.left })
+ module.setCoords()
+ })
+ },
+ })
+ }
+ canvas.renderAll()
+ }
+
+ const moduleRowRemove = (type) => {
+ const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
+ const rowModules = getRowModules(activeModule)
+ const otherModules = getOtherModules(rowModules)
+ const objects = getObjects()
+ let targetModules = []
+ const topModules = otherModules.filter((module) => activeModule.top > module.top).sort((a, b) => b.top - a.top)
+ const bottomModules = otherModules.filter((module) => activeModule.top < module.top).sort((a, b) => a.top - b.top)
+ let height = -1
+ const moduleSetupSurface = canvas
+ .getObjects()
+ .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
+ let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
+
+ canvas.discardActiveObject()
+ canvas.remove(...rowModules)
+ canvas.renderAll()
+
+ if (type === MODULE_REMOVE_TYPE.TOP) {
+ bottomModules.forEach((module) => {
+ module.originPos = {
+ left: module.left,
+ top: module.top,
+ }
+ if (height === -1) height = module.top - activeModule.top
+ module.set({ top: module.top - height })
+ module.setCoords()
+ canvas.renderAll()
+ isOverlapOtherModules.push(getIsOverlapOtherModules(module, topModules))
+ isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
+ isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
+ })
+ targetModules = bottomModules
+ } else if (type === MODULE_REMOVE_TYPE.BOTTOM) {
+ topModules.forEach((module) => {
+ module.originPos = {
+ left: module.left,
+ top: module.top,
+ }
+ if (height === -1) height = activeModule.top - module.top
+ module.set({ top: module.top + height })
+ module.setCoords()
+ canvas.renderAll()
+ isOverlapOtherModules.push(getIsOverlapOtherModules(module, bottomModules))
+ isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
+ isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
+ })
+ targetModules = topModules
+ } else if (type === MODULE_REMOVE_TYPE.VERTICAL_SIDE) {
+ topModules.forEach((module) => {
+ module.originPos = {
+ left: module.left,
+ top: module.top,
+ }
+ if (height === -1) height = activeModule.top - module.top
+ module.set({ top: module.top + height / 2 })
+ module.setCoords()
+ canvas.renderAll()
+ })
+
+ bottomModules.forEach((module) => {
+ module.originPos = {
+ left: module.left,
+ top: module.top,
+ }
+ if (height === -1) height = module.top - activeModule.top
+ module.set({ top: module.top - height / 2 })
+ module.setCoords()
+ canvas.renderAll()
+ })
+
+ const sideModules = [...topModules, ...bottomModules]
+ canvas.renderAll()
+ sideModules.forEach((module) => {
+ isOverlapOtherModules.push(
+ getIsOverlapOtherModules(
+ module,
+ sideModules.filter((m) => m.id !== module.id),
+ ),
+ )
+ isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
+ isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
+ })
+ targetModules = sideModules
+ }
+
+ if (
+ (isOverlapOtherModules.some((isOverlap) => isOverlap) ||
+ isOverlapObjects.some((isOverlap) => isOverlap) ||
+ isOutsideSurface.some((isOutside) => isOutside)) &&
+ type !== MODULE_REMOVE_TYPE.NONE
+ ) {
+ swalFire({
+ title: isOverlapOtherModules.some((isOverlap) => isOverlap)
+ ? '겹치는 모듈이 있습니다.'
+ : isOverlapObjects.some((isOverlap) => isOverlap)
+ ? '모듈이 오브젝트와 겹칩니다.'
+ : '영역 밖',
+ icon: 'error',
+ type: 'confirm',
+ confirmFn: () => {
+ canvas.add(...rowModules)
+ targetModules.forEach((module) => {
+ module.set({ top: module.originPos.top, left: module.originPos.left })
+ module.setCoords()
+ })
+ },
+ })
+ }
+ canvas.renderAll()
+ }
+
+ const moduleColumnInsert = (type) => {
+ const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
+ const columnModules = getColumnModules(activeModule)
+ let otherModules = getOtherModules(columnModules)
+ const targetModules =
+ type === MODULE_INSERT_TYPE.LEFT
+ ? otherModules.filter((module) => module.left < activeModule.left).sort((a, b) => a.left - b.left)
+ : otherModules.filter((module) => module.left > activeModule.left).sort((a, b) => b.left - a.left)
+ const objects = getObjects()
+ const copyModules = []
+ const moduleSetupSurface = canvas
+ .getObjects()
+ .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
+ let width = -1
+ let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
+ if (targetModules.length === 0) {
+ swalFire({
+ title: '마지막 모듈입니다.',
+ icon: 'error',
+ type: 'alert',
+ })
+ return
+ }
+ canvas.discardActiveObject()
+ targetModules.forEach((module) => {
+ if (width === -1)
+ width = type === MODULE_INSERT_TYPE.LEFT ? Number(activeModule.left) - Number(module.left) : Number(module.left) - Number(activeModule.left)
+ const { top, left } = getPosotion(module, type, width, false)
+ module.originPos = {
+ left: module.left,
+ top: module.top,
+ }
+ module.set({ left, top })
+ canvas.renderAll()
+ if (objects.length > 0) {
+ isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
+ }
+
+ isOutsideSurface.push(
+ !turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(module, true)) ||
+ !turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(moduleSetupSurface, true)),
+ )
+ module.setCoords()
+ })
+ otherModules = getOtherModules(columnModules)
+ columnModules.forEach((module) => {
+ const { top, left } = getPosotion(module, type, width, false)
+ const moduleOptions = { ...module, left, top, id: uuidv4() }
+ const copyModule = new QPolygon(module.points, moduleOptions)
+ canvas.add(copyModule)
+ copyModules.push(copyModule)
+ canvas.renderAll()
+
+ if (otherModules.length > 0) {
+ isOverlapOtherModules.push(
+ otherModules.some(
+ (otherModule) =>
+ turf.booleanOverlap(polygonToTurfPolygon(copyModule, true), polygonToTurfPolygon(otherModule, true)) ||
+ turf.booleanWithin(polygonToTurfPolygon(copyModule, true), polygonToTurfPolygon(otherModule, true)),
+ ),
+ )
+ }
+
+ if (objects.length > 0) {
+ isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
+ }
+
+ isOutsideSurface.push(
+ !turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(copyModule, true)) ||
+ !turf.booleanWithin(polygonToTurfPolygon(copyModule, true), polygonToTurfPolygon(moduleSetupSurface, true)),
+ )
+ module.setCoords()
+ })
+
+ if (
+ isOverlapOtherModules.some((isOverlap) => isOverlap) ||
+ isOverlapObjects.some((isOverlap) => isOverlap) ||
+ isOutsideSurface.some((isOutside) => isOutside)
+ ) {
+ swalFire({
+ title: isOverlapOtherModules.some((isOverlap) => isOverlap)
+ ? '겹치는 모듈이 있습니다.'
+ : isOverlapObjects.some((isOverlap) => isOverlap)
+ ? '모듈이 오브젝트와 겹칩니다.'
+ : '영역 밖',
+ icon: 'error',
+ type: 'confirm',
+ confirmFn: () => {
+ targetModules.forEach((module) => {
+ module.set({ top: module.originPos.top, left: module.originPos.left })
+ module.setCoords()
+ })
+ canvas.renderAll()
+ copyModules.forEach((module) => {
+ canvas.remove(module)
+ })
+ canvas.renderAll()
+ },
+ })
+ }
+ }
+
+ const muduleRowInsert = (type) => {
+ console.log('🚀 ~ muduleRowInsert ~ type:', type)
+ const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
+ const rowModules = getRowModules(activeModule)
+ console.log('🚀 ~ muduleRowInsert ~ rowModules:', rowModules)
+ let otherModules = getOtherModules(rowModules)
+ const targetModules =
+ type === MODULE_INSERT_TYPE.TOP
+ ? otherModules.filter((module) => module.top < activeModule.top).sort((a, b) => b.top - a.top)
+ : otherModules.filter((module) => module.top > activeModule.top).sort((a, b) => a.top - b.top)
+ console.log('🚀 ~ muduleRowInsert ~ targetModules:', targetModules)
+ if (targetModules.length === 0) {
+ swalFire({
+ title: '마지막 모듈입니다.',
+ icon: 'error',
+ type: 'alert',
+ })
+ return
+ }
+ const objects = getObjects()
+ const copyModules = []
+ const moduleSetupSurface = canvas
+ .getObjects()
+ .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
+ let height = -1
+ let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
+ canvas.discardActiveObject()
+ targetModules.forEach((module) => {
+ if (height === -1)
+ height = type === MODULE_INSERT_TYPE.TOP ? Number(activeModule.top) - Number(module.top) : Number(module.top) - Number(activeModule.top)
+ const { top, left } = getPosotion(module, type, height, false)
+ module.originPos = {
+ left: module.left,
+ top: module.top,
+ }
+ module.set({ left, top })
+ canvas.renderAll()
+ if (objects.length > 0) {
+ isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
+ }
+
+ isOutsideSurface.push(
+ !turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(module, true)) ||
+ !turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(moduleSetupSurface, true)),
+ )
+ module.setCoords()
+ })
+ otherModules = getOtherModules(rowModules)
+ rowModules.forEach((module) => {
+ const { top, left } = getPosotion(module, type, height, false)
+ const moduleOptions = { ...module, left, top, id: uuidv4() }
+ const copyModule = new QPolygon(module.points, moduleOptions)
+ canvas.add(copyModule)
+ copyModules.push(copyModule)
+ canvas.renderAll()
+
+ if (otherModules.length > 0) {
+ isOverlapOtherModules.push(
+ otherModules.some(
+ (otherModule) =>
+ turf.booleanOverlap(polygonToTurfPolygon(copyModule, true), polygonToTurfPolygon(otherModule, true)) ||
+ turf.booleanWithin(polygonToTurfPolygon(copyModule, true), polygonToTurfPolygon(otherModule, true)),
+ ),
+ )
+ }
+
+ if (objects.length > 0) {
+ isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
+ }
+
+ isOutsideSurface.push(
+ !turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(copyModule, true)) ||
+ !turf.booleanWithin(polygonToTurfPolygon(copyModule, true), polygonToTurfPolygon(moduleSetupSurface, true)),
+ )
+ module.setCoords()
+ })
+
+ if (
+ isOverlapOtherModules.some((isOverlap) => isOverlap) ||
+ isOverlapObjects.some((isOverlap) => isOverlap) ||
+ isOutsideSurface.some((isOutside) => isOutside)
+ ) {
+ swalFire({
+ title: isOverlapOtherModules.some((isOverlap) => isOverlap)
+ ? '겹치는 모듈이 있습니다.'
+ : isOverlapObjects.some((isOverlap) => isOverlap)
+ ? '모듈이 오브젝트와 겹칩니다.'
+ : '영역 밖',
+ icon: 'error',
+ type: 'confirm',
+ confirmFn: () => {
+ targetModules.forEach((module) => {
+ module.set({ top: module.originPos.top, left: module.originPos.left })
+ module.setCoords()
+ })
+ canvas.renderAll()
+ copyModules.forEach((module) => {
+ canvas.remove(module)
+ })
+ canvas.renderAll()
+ },
+ })
+ }
+ }
+
+ const getRowModules = (target) => {
+ return canvas
+ .getObjects()
+ .filter((obj) => target.surfaceId === obj.surfaceId && obj.name === POLYGON_TYPE.MODULE && obj.top === target.top)
+ .sort((a, b) => a.left - b.left)
+ }
+
+ const getColumnModules = (target) => {
+ return canvas
+ .getObjects()
+ .filter((obj) => target.surfaceId === obj.surfaceId && obj.name === POLYGON_TYPE.MODULE && obj.left === target.left)
+ .sort((a, b) => a.top - b.top)
+ }
+
+ const getPosotion = (target, direction, length, hasMargin = false) => {
+ let top = target.top
+ let left = target.left
+
+ if (direction === 'up') {
+ top = Number(target.top) - Number(length)
+ top = hasMargin ? top - Number(target.height) : top
+ } else if (direction === 'down') {
+ top = Number(target.top) + Number(length)
+ top = hasMargin ? top + Number(target.height) : top
+ } else if (direction === 'left') {
+ left = Number(target.left) - Number(length)
+ left = hasMargin ? left - Number(target.width) : left
+ } else if (direction === 'right') {
+ left = Number(target.left) + Number(length)
+ left = hasMargin ? left + Number(target.width) : left
+ }
+ return { top, left }
+ }
+
+ const getOtherModules = (modules) => {
+ const moduleIds = modules.map((module) => module.id)
+ return canvas
+ .getObjects()
+ .filter((obj) => obj.surfaceId === modules[0].surfaceId && obj.name === POLYGON_TYPE.MODULE && !moduleIds.includes(obj.id))
+ }
+
+ const getObjects = () => {
+ return canvas
+ ?.getObjects()
+ .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,
+ moduleCopy,
+ moduleMultiCopy,
+ moduleColumnRemove,
+ moduleRowRemove,
+ moduleColumnInsert,
+ muduleRowInsert,
+ }
+}
diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js
index d9f8ae84..f654145d 100644
--- a/src/hooks/module/useModuleBasicSetting.js
+++ b/src/hooks/module/useModuleBasicSetting.js
@@ -428,7 +428,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])) //겹치는지 확인
@@ -567,35 +568,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
+ // }
/**
* 배치면 안에 있는지 확인
@@ -2141,36 +2142,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
@@ -2431,6 +2402,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,
@@ -2438,5 +2442,6 @@ export function useModuleBasicSetting() {
restoreModuleInstArea,
manualFlatroofModuleSetup,
autoFlatroofModuleSetup,
+ checkModuleDisjointObjects,
}
}
diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js
index 441a06030..1c1dca34 100644
--- a/src/hooks/option/useCanvasSetting.js
+++ b/src/hooks/option/useCanvasSetting.js
@@ -269,17 +269,6 @@ export function useCanvasSetting() {
roofSizeSet: item.roofSizeSet,
roofAngleSet: item.roofAngleSet,
}
-
- roofsArray = {
- roofApply: true,
- roofSeq: 1,
- roofMatlCd: 'ROOF_ID_WA_53A',
- roofWidth: 265,
- roofHeight: 235,
- roofHajebichi: 0,
- roofGap: 'HEI_455',
- roofLayout: 'P',
- }
})
} else {
roofsRow = [
diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js
index a2c7b483..6c1ace5c 100644
--- a/src/hooks/roofcover/useRoofAllocationSetting.js
+++ b/src/hooks/roofcover/useRoofAllocationSetting.js
@@ -13,6 +13,7 @@ import useMenu from '@/hooks/common/useMenu'
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
import { menuTypeState } from '@/store/menuAtom'
import { useRoofFn } from '@/hooks/common/useRoofFn'
+import { ROOF_MATERIAL_LAYOUT } from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting'
// 지붕면 할당
export function useRoofAllocationSetting(id) {
@@ -32,7 +33,7 @@ export function useRoofAllocationSetting(id) {
const [currentRoofMaterial, setCurrentRoofMaterial] = useState(roofMaterials[0]) // 팝업 내 기준 지붕재
const [roofList, setRoofList] = useRecoilState(addedRoofsState) // 배치면 초기설정에서 선택한 지붕재 배열
const [editingLines, setEditingLines] = useState([])
- const isFirstRef = useRef(0)
+ const [currentRoofList, setCurrentRoofList] = useState(roofList)
const { setSurfaceShapePattern } = useRoofFn()
@@ -76,20 +77,25 @@ export function useRoofAllocationSetting(id) {
}, [])
const onAddRoofMaterial = () => {
- if (roofList.length >= 4) {
+ if (currentRoofList.length >= 4) {
swalFire({ type: 'alert', icon: 'error', text: getMessage('지붕재는 4개까지 선택 가능합니다.') })
return
}
- setRoofList([...roofList, { ...currentRoofMaterial, selected: false, id: currentRoofMaterial.roofMatlCd, name: currentRoofMaterial.roofMatlNm }])
+ setCurrentRoofList([
+ ...currentRoofList,
+ { ...currentRoofMaterial, selected: false, id: currentRoofMaterial.roofMatlCd, name: currentRoofMaterial.roofMatlNm },
+ ])
}
const onDeleteRoofMaterial = (idx) => {
- setRoofList([...roofList.filter((_, index) => index !== idx)])
+ const isSelected = currentRoofList[idx].selected
+ const newRoofList = [...currentRoofList].filter((_, index) => index !== idx)
+ if (isSelected) {
+ newRoofList[0].selected = true
+ }
+ setCurrentRoofList(newRoofList)
}
- const { handleMenu } = useMenu()
- const [currentMenu, setCurrentMenu] = useRecoilState(currentMenuState)
-
// 선택한 지붕재로 할당
const handleSave = () => {
// 모두 actualSize 있으면 바로 적용 없으면 actualSize 설정
@@ -102,7 +108,7 @@ export function useRoofAllocationSetting(id) {
// 지붕재 오른쪽 마우스 클릭 후 단일로 지붕재 변경 필요한 경우
const handleSaveContext = () => {
- const selectedRoofMaterial = roofList.find((roof) => roof.selected)
+ const selectedRoofMaterial = currentRoofList.find((roof) => roof.selected)
setSurfaceShapePattern(currentObject, roofDisplay.column, false, selectedRoofMaterial)
closeAll()
}
@@ -169,11 +175,11 @@ export function useRoofAllocationSetting(id) {
setBasicSetting((prev) => {
return {
...prev,
- selectedRoofMaterial: roofList.find((roof) => roof.selected),
+ selectedRoofMaterial: currentRoofList.find((roof) => roof.selected),
}
})
- setRoofList(roofList)
+ setRoofList(currentRoofList)
const roofs = canvas.getObjects().filter((obj) => obj.name === 'roof')
@@ -182,7 +188,12 @@ export function useRoofAllocationSetting(id) {
roof.set({
isFixed: true,
})
- setSurfaceShapePattern(roof, roofDisplay.column)
+ setSurfaceShapePattern(
+ roof,
+ roofDisplay.column,
+ false,
+ currentRoofList.find((roof) => roof.selected),
+ )
drawDirectionArrow(roof)
})
@@ -216,54 +227,53 @@ export function useRoofAllocationSetting(id) {
// 지붕재 변경
const handleChangeRoofMaterial = (value, index) => {
- if (isFirstRef.current === 0) {
- isFirstRef.current++
- return
- }
+ const selectedIndex = roofMaterials.findIndex((roof) => roof.selected)
const selectedRoofMaterial = roofMaterials.find((roof) => roof.roofMatlCd === value.id)
- const newRoofList = roofList.map((roof, idx) => {
+ const newRoofList = currentRoofList.map((roof, idx) => {
if (idx === index) {
return { ...selectedRoofMaterial }
}
return roof
})
- setRoofList(newRoofList)
+ newRoofList[selectedIndex].selected = true
+
+ setCurrentRoofList(newRoofList)
}
// 기본 지붕재 radio값 변경
const handleDefaultRoofMaterial = (index) => {
- const newRoofList = roofList.map((roof, idx) => {
+ const newRoofList = currentRoofList.map((roof, idx) => {
return { ...roof, selected: idx === index }
})
- setRoofList(newRoofList)
+ setCurrentRoofList(newRoofList)
}
// 서까래 변경
const handleChangeRaft = (e, index) => {
- const raftValue = e.value
+ const raftValue = e.clCode
- const newRoofList = roofList.map((roof, idx) => {
+ const newRoofList = currentRoofList.map((roof, idx) => {
if (idx === index) {
return { ...roof, raft: raftValue }
}
return roof
})
- setRoofList(newRoofList)
+ setCurrentRoofList(newRoofList)
}
const handleChangeLayout = (layoutValue, index) => {
- const newRoofList = roofList.map((roof, idx) => {
+ const newRoofList = currentRoofList.map((roof, idx) => {
if (idx === index) {
return { ...roof, layout: layoutValue }
}
return roof
})
- setRoofList(newRoofList)
+ setCurrentRoofList(newRoofList)
}
return {
@@ -278,11 +288,11 @@ export function useRoofAllocationSetting(id) {
setBasicSetting,
currentRoofMaterial,
setCurrentRoofMaterial,
- roofList,
handleDefaultRoofMaterial,
handleChangeRoofMaterial,
handleChangeRaft,
handleChangeLayout,
handleSaveContext,
+ currentRoofList,
}
}
diff --git a/src/hooks/useContextMenu.js b/src/hooks/useContextMenu.js
index 38564f7b..e0a2cf0f 100644
--- a/src/hooks/useContextMenu.js
+++ b/src/hooks/useContextMenu.js
@@ -23,7 +23,7 @@ import { useCommonUtils } from './common/useCommonUtils'
import { useMessage } from '@/hooks/useMessage'
import { useCanvasEvent } from '@/hooks/useCanvasEvent'
import { contextMenuListState, contextMenuState } from '@/store/contextMenu'
-import PanelEdit from '@/components/floor-plan/modal/module/PanelEdit'
+import PanelEdit, { PANEL_EDIT_TYPE } from '@/components/floor-plan/modal/module/PanelEdit'
import DimensionLineSetting from '@/components/floor-plan/modal/dimensionLine/DimensionLineSetting'
import ColumnRemove from '@/components/floor-plan/modal/module/column/ColumnRemove'
import ColumnInsert from '@/components/floor-plan/modal/module/column/ColumnInsert'
@@ -36,6 +36,7 @@ import { fontSelector, globalFontAtom } from '@/store/fontAtom'
import { useLine } from '@/hooks/useLine'
import { useSwal } from '@/hooks/useSwal'
import ContextRoofAllocationSetting from '@/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting'
+import { useRoofFn } from '@/hooks/common/useRoofFn'
export function useContextMenu() {
const canvas = useRecoilValue(canvasState)
@@ -59,6 +60,7 @@ export function useContextMenu() {
const { addLine, removeLine } = useLine()
const commonTextFont = useRecoilValue(fontSelector('commonText'))
const { swalFire } = useSwal()
+ const { removeRoofMaterial, removeAllRoofMaterial } = useRoofFn()
const currentMenuSetting = () => {
switch (currentMenu) {
@@ -110,10 +112,12 @@ export function useContextMenu() {
{
id: 'roofMaterialRemove',
name: getMessage('contextmenu.roof.material.remove'),
+ fn: () => removeRoofMaterial(),
},
{
id: 'roofMaterialRemoveAll',
name: getMessage('contextmenu.roof.material.remove.all'),
+ fn: () => removeAllRoofMaterial(),
},
{
id: 'selectMove',
@@ -609,24 +613,24 @@ export function useContextMenu() {
{
id: 'move',
name: getMessage('contextmenu.move'),
- component: ,
+ component: ,
},
{
id: 'copy',
name: getMessage('contextmenu.copy'),
- component: ,
+ component: ,
},
],
[
{
id: 'columnMove',
name: getMessage('contextmenu.column.move'),
- component: ,
+ component: ,
},
{
id: 'columnCopy',
name: getMessage('contextmenu.column.copy'),
- component: ,
+ component: ,
},
{
id: 'columnRemove',
@@ -643,12 +647,12 @@ export function useContextMenu() {
{
id: 'rowMove',
name: getMessage('contextmenu.row.move'),
- component: ,
+ component: ,
},
{
id: 'rowCopy',
name: getMessage('contextmenu.row.copy'),
- component: ,
+ component: ,
},
{
id: 'rowRemove',
diff --git a/src/store/settingAtom.js b/src/store/settingAtom.js
index 2350b0f5..1b837fdd 100644
--- a/src/store/settingAtom.js
+++ b/src/store/settingAtom.js
@@ -224,9 +224,9 @@ export const roofMaterialsAtom = atom({
export const selectedRoofMaterialSelector = selector({
key: 'selectedRoofMaterialSelector',
get: ({ get }) => {
- const basicSetting = get(basicSettingState)
+ const addedRoofs = get(addedRoofsState)
- return { ...basicSetting.selectedRoofMaterial }
+ return addedRoofs.find((roof) => roof.selected)
},
})
@@ -239,16 +239,6 @@ export const roofMaterialsSelector = selector({
},
})
-// 지붕면 할당에서 추가된 지붕재 목록
-export const addedRoofsSelector = selector({
- key: 'addedRoofsSelector',
- get: ({ get }) => {
- const basicSetting = get(basicSettingState)
- return basicSetting.roofs
- },
- dangerouslyAllowMutability: true,
-})
-
/**
* 현재 선택된 물건 번호
*/