polygon name 수정, 지붕 나누기 수정
This commit is contained in:
parent
da26628f69
commit
0adfe0916c
@ -225,9 +225,9 @@ export function useCanvasSetting() {
|
|||||||
const option1 = settingModalFirstOptions.option1
|
const option1 = settingModalFirstOptions.option1
|
||||||
|
|
||||||
// 'allocDisplay' 할당 표시
|
// 'allocDisplay' 할당 표시
|
||||||
// 'outlineDisplay' 외벽선 표시 'outerLine', 'wallLine'
|
// 'outlineDisplay' 외벽선 표시 'outerLine', POLYGON_TYPE.WALL
|
||||||
// 'gridDisplay' 그리드 표시 'lindGrid', 'dotGrid'
|
// 'gridDisplay' 그리드 표시 'lindGrid', 'dotGrid'
|
||||||
// 'lineDisplay' 지붕선 표시 'roof', 'roofBase'
|
// 'lineDisplay' 지붕선 표시 'roof', POLYGON_TYPE.ROOF
|
||||||
// 'wordDisplay' 문자 표시
|
// 'wordDisplay' 문자 표시
|
||||||
// 'circuitNumDisplay' 회로번호 표시
|
// 'circuitNumDisplay' 회로번호 표시
|
||||||
// 'flowDisplay' 흐름방향 표시 'arrow'
|
// 'flowDisplay' 흐름방향 표시 'arrow'
|
||||||
@ -244,13 +244,13 @@ export function useCanvasSetting() {
|
|||||||
optionName = ['1']
|
optionName = ['1']
|
||||||
break
|
break
|
||||||
case 'outlineDisplay': //외벽선 표시
|
case 'outlineDisplay': //외벽선 표시
|
||||||
optionName = ['outerLine', 'wallLine']
|
optionName = ['outerLine', POLYGON_TYPE.WALL]
|
||||||
break
|
break
|
||||||
case 'gridDisplay': //그리드 표시
|
case 'gridDisplay': //그리드 표시
|
||||||
optionName = ['lindGrid', 'dotGrid']
|
optionName = ['lindGrid', 'dotGrid']
|
||||||
break
|
break
|
||||||
case 'lineDisplay': //지붕선 표시
|
case 'lineDisplay': //지붕선 표시
|
||||||
optionName = ['roof', 'roofBase']
|
optionName = ['roof', POLYGON_TYPE.ROOF]
|
||||||
break
|
break
|
||||||
case 'wordDisplay': //문자 표시
|
case 'wordDisplay': //문자 표시
|
||||||
optionName = ['6']
|
optionName = ['6']
|
||||||
|
|||||||
@ -12,9 +12,9 @@ export function useFirstOption() {
|
|||||||
const option1 = settingModalFirstOptions.option1
|
const option1 = settingModalFirstOptions.option1
|
||||||
|
|
||||||
// 'allocDisplay' 할당 표시
|
// 'allocDisplay' 할당 표시
|
||||||
// 'outlineDisplay' 외벽선 표시 'outerLine', 'wallLine'
|
// 'outlineDisplay' 외벽선 표시 'outerLine', POLYGON_TYPE.WALL
|
||||||
// 'gridDisplay' 그리드 표시 'lindGrid', 'dotGrid'
|
// 'gridDisplay' 그리드 표시 'lindGrid', 'dotGrid'
|
||||||
// 'lineDisplay' 지붕선 표시 'roof', 'roofBase'
|
// 'lineDisplay' 지붕선 표시 'roof', POLYGON_TYPE.ROOF
|
||||||
// 'wordDisplay' 문자 표시
|
// 'wordDisplay' 문자 표시
|
||||||
// 'circuitNumDisplay' 회로번호 표시
|
// 'circuitNumDisplay' 회로번호 표시
|
||||||
// 'flowDisplay' 흐름방향 표시 'arrow'
|
// 'flowDisplay' 흐름방향 표시 'arrow'
|
||||||
@ -30,13 +30,13 @@ export function useFirstOption() {
|
|||||||
optionName = ['1']
|
optionName = ['1']
|
||||||
break
|
break
|
||||||
case 'outlineDisplay': //외벽선 표시
|
case 'outlineDisplay': //외벽선 표시
|
||||||
optionName = ['outerLine', 'wallLine']
|
optionName = ['outerLine', POLYGON_TYPE.WALL]
|
||||||
break
|
break
|
||||||
case 'gridDisplay': //그리드 표시
|
case 'gridDisplay': //그리드 표시
|
||||||
optionName = ['lineGrid', 'dotGrid', 'adsorptionPoint', 'tempGrid']
|
optionName = ['lineGrid', 'dotGrid', 'adsorptionPoint', 'tempGrid']
|
||||||
break
|
break
|
||||||
case 'lineDisplay': //지붕선 표시
|
case 'lineDisplay': //지붕선 표시
|
||||||
optionName = ['roof', 'roofBase']
|
optionName = ['roof', POLYGON_TYPE.ROOF]
|
||||||
break
|
break
|
||||||
case 'wordDisplay': //문자 표시
|
case 'wordDisplay': //문자 표시
|
||||||
optionName = ['6']
|
optionName = ['6']
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import {
|
|||||||
outerLineLength2State,
|
outerLineLength2State,
|
||||||
outerLineTypeState,
|
outerLineTypeState,
|
||||||
} from '@/store/outerLineAtom'
|
} from '@/store/outerLineAtom'
|
||||||
import { calculateIntersection, distanceBetweenPoints, findClosestPoint, polygonToTurfPolygon } from '@/util/canvas-util'
|
import { calculateIntersection, distanceBetweenPoints, findClosestPoint, isPointOnLine, polygonToTurfPolygon } from '@/util/canvas-util'
|
||||||
import { fabric } from 'fabric'
|
import { fabric } from 'fabric'
|
||||||
import { useAdsorptionPoint } from '@/hooks/useAdsorptionPoint'
|
import { useAdsorptionPoint } from '@/hooks/useAdsorptionPoint'
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
@ -23,6 +23,7 @@ import { booleanPointInPolygon } from '@turf/turf'
|
|||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
import { calculateAngle } from '@/util/qpolygon-utils'
|
import { calculateAngle } from '@/util/qpolygon-utils'
|
||||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||||
|
import { POLYGON_TYPE } from '@/common/common'
|
||||||
|
|
||||||
// 보조선 작성
|
// 보조선 작성
|
||||||
export function useAuxiliaryDrawing(id) {
|
export function useAuxiliaryDrawing(id) {
|
||||||
@ -80,7 +81,7 @@ export function useAuxiliaryDrawing(id) {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// innerLines가 있을경우 삭제
|
// innerLines가 있을경우 삭제
|
||||||
const roofs = canvas?.getObjects().filter((obj) => obj.name === 'roofBase')
|
const roofs = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||||
if (roofs.length === 0) {
|
if (roofs.length === 0) {
|
||||||
swalFire({ text: '지붕형상이 없습니다.' })
|
swalFire({ text: '지붕형상이 없습니다.' })
|
||||||
closePopup(id)
|
closePopup(id)
|
||||||
@ -561,7 +562,7 @@ export function useAuxiliaryDrawing(id) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const roofBases = canvas.getObjects().filter((obj) => obj.name === 'roofBase')
|
const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||||
/*const allLines = [...auxiliaryLines]
|
/*const allLines = [...auxiliaryLines]
|
||||||
|
|
||||||
roofBases.forEach((roofBase) => {
|
roofBases.forEach((roofBase) => {
|
||||||
@ -611,6 +612,7 @@ export function useAuxiliaryDrawing(id) {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
lineHistory.current.push(newLine)
|
lineHistory.current.push(newLine)
|
||||||
|
lineHistory.current = lineHistory.current.filter((history) => history !== line1)
|
||||||
removeLine(line1)
|
removeLine(line1)
|
||||||
intersectionPoints.current.push(...interSectionPointsWithRoofLines)
|
intersectionPoints.current.push(...interSectionPointsWithRoofLines)
|
||||||
return
|
return
|
||||||
@ -659,6 +661,7 @@ export function useAuxiliaryDrawing(id) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
lineHistory.current.push(newLine)
|
lineHistory.current.push(newLine)
|
||||||
|
lineHistory.current = lineHistory.current.filter((history) => history !== line1)
|
||||||
removeLine(line1)
|
removeLine(line1)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -742,7 +745,7 @@ export function useAuxiliaryDrawing(id) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const roofBases = canvas.getObjects().filter((obj) => obj.name === 'roofBase')
|
const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||||
|
|
||||||
//lineHistory.current에 있는 선들 중 startPoint와 endPoint가 겹치는 line은 제거
|
//lineHistory.current에 있는 선들 중 startPoint와 endPoint가 겹치는 line은 제거
|
||||||
// 겹치는 선 하나는 canvas에서 제거한다.
|
// 겹치는 선 하나는 canvas에서 제거한다.
|
||||||
@ -772,9 +775,13 @@ export function useAuxiliaryDrawing(id) {
|
|||||||
})
|
})
|
||||||
const roofInnerLines = innerLines.filter((line) => {
|
const roofInnerLines = innerLines.filter((line) => {
|
||||||
const inPolygon1 =
|
const inPolygon1 =
|
||||||
tempPolygonPoints.some((point) => point.x === line.x1 && point.y === line.y1) || roofBase.inPolygon({ x: line.x1, y: line.y1 })
|
tempPolygonPoints.some((point) => point.x === line.x1 && point.y === line.y1) ||
|
||||||
|
roofBase.inPolygon({ x: line.x1, y: line.y1 }) ||
|
||||||
|
roofBase.lines.some((line) => isPointOnLine(line, { x: line.x1, y: line.y1 }))
|
||||||
const inPolygon2 =
|
const inPolygon2 =
|
||||||
tempPolygonPoints.some((point) => point.x === line.x2 && point.y === line.y2) || roofBase.inPolygon({ x: line.x2, y: line.y2 })
|
tempPolygonPoints.some((point) => point.x === line.x2 && point.y === line.y2) ||
|
||||||
|
roofBase.inPolygon({ x: line.x2, y: line.y2 }) ||
|
||||||
|
roofBase.lines.some((line) => isPointOnLine(line, { x: line.x2, y: line.y2 }))
|
||||||
|
|
||||||
if (inPolygon1 && inPolygon2) {
|
if (inPolygon1 && inPolygon2) {
|
||||||
line.attributes = { ...line.attributes, roofId: roofBase.id }
|
line.attributes = { ...line.attributes, roofId: roofBase.id }
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { useRecoilValue } from 'recoil'
|
|||||||
import { ANGLE_TYPE, canvasState, currentAngleTypeSelector, pitchTextSelector } from '@/store/canvasAtom'
|
import { ANGLE_TYPE, canvasState, currentAngleTypeSelector, pitchTextSelector } from '@/store/canvasAtom'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useEvent } from '@/hooks/useEvent'
|
import { useEvent } from '@/hooks/useEvent'
|
||||||
import { LINE_TYPE } from '@/common/common'
|
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
|
||||||
import { useLine } from '@/hooks/useLine'
|
import { useLine } from '@/hooks/useLine'
|
||||||
import { useMode } from '@/hooks/useMode'
|
import { useMode } from '@/hooks/useMode'
|
||||||
import { outerLineFixState } from '@/store/outerLineAtom'
|
import { outerLineFixState } from '@/store/outerLineAtom'
|
||||||
@ -54,7 +54,7 @@ export function useEavesGableEdit(id) {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === 'wallLine')
|
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
||||||
wallLines.forEach((wallLine) => {
|
wallLines.forEach((wallLine) => {
|
||||||
convertPolygonToLines(wallLine)
|
convertPolygonToLines(wallLine)
|
||||||
})
|
})
|
||||||
@ -160,7 +160,7 @@ export function useEavesGableEdit(id) {
|
|||||||
attributes,
|
attributes,
|
||||||
})
|
})
|
||||||
|
|
||||||
const roofBases = canvas?.getObjects().filter((obj) => obj.name === 'roofBase')
|
const roofBases = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||||
|
|
||||||
roofBases.forEach((roof) => {
|
roofBases.forEach((roof) => {
|
||||||
roof.innerLines.forEach((line) => {
|
roof.innerLines.forEach((line) => {
|
||||||
@ -169,7 +169,7 @@ export function useEavesGableEdit(id) {
|
|||||||
canvas.remove(roof)
|
canvas.remove(roof)
|
||||||
})
|
})
|
||||||
|
|
||||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === 'wallLine')
|
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
||||||
const removeTargets = canvas.getObjects().filter((obj) => obj.name === 'pitchText')
|
const removeTargets = canvas.getObjects().filter((obj) => obj.name === 'pitchText')
|
||||||
removeTargets.forEach((obj) => {
|
removeTargets.forEach((obj) => {
|
||||||
canvas.remove(obj)
|
canvas.remove(obj)
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import { usePopup } from '@/hooks/usePopup'
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useEffect, useRef, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
import { useEvent } from '@/hooks/useEvent'
|
import { useEvent } from '@/hooks/useEvent'
|
||||||
|
import { POLYGON_TYPE } from '@/common/common'
|
||||||
|
|
||||||
//동선이동 형 올림 내림
|
//동선이동 형 올림 내림
|
||||||
export function useMovementSetting(id) {
|
export function useMovementSetting(id) {
|
||||||
@ -41,7 +42,7 @@ export function useMovementSetting(id) {
|
|||||||
}, [type])
|
}, [type])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === 'wallLine') // 기존 wallLine의 visible false
|
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL) // 기존 wallLine의 visible false
|
||||||
wallLines.forEach((line) => {
|
wallLines.forEach((line) => {
|
||||||
line.set({ visible: false })
|
line.set({ visible: false })
|
||||||
})
|
})
|
||||||
@ -55,7 +56,7 @@ export function useMovementSetting(id) {
|
|||||||
addCanvasMouseEventListener('mouse:move', mouseMoveEvent)
|
addCanvasMouseEventListener('mouse:move', mouseMoveEvent)
|
||||||
return () => {
|
return () => {
|
||||||
initEvent()
|
initEvent()
|
||||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === 'wallLine')
|
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
||||||
wallLines.forEach((line) => {
|
wallLines.forEach((line) => {
|
||||||
line.set({ visible: true })
|
line.set({ visible: true })
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { useEffect, useRef } from 'react'
|
import { useEffect, useRef } from 'react'
|
||||||
import { LINE_TYPE } from '@/common/common'
|
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
|
||||||
import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil'
|
import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil'
|
||||||
import { canvasState, currentObjectState } from '@/store/canvasAtom'
|
import { canvasState, currentObjectState } from '@/store/canvasAtom'
|
||||||
import { useMode } from '@/hooks/useMode'
|
import { useMode } from '@/hooks/useMode'
|
||||||
@ -135,7 +135,7 @@ export function usePropertiesSetting(id) {
|
|||||||
hideLine(line)
|
hideLine(line)
|
||||||
})
|
})
|
||||||
|
|
||||||
const wall = addPolygonByLines(lines, { name: 'wallLine', fill: 'transparent', stroke: 'black' })
|
const wall = addPolygonByLines(lines, { name: POLYGON_TYPE.WALL, fill: 'transparent', stroke: 'black' })
|
||||||
|
|
||||||
wall.lines = [...lines]
|
wall.lines = [...lines]
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import { useSwal } from '@/hooks/useSwal'
|
|||||||
import { usePolygon } from '@/hooks/usePolygon'
|
import { usePolygon } from '@/hooks/usePolygon'
|
||||||
import { roofDisplaySelector } from '@/store/settingAtom'
|
import { roofDisplaySelector } from '@/store/settingAtom'
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
|
import { POLYGON_TYPE } from '@/common/common'
|
||||||
|
|
||||||
// 지붕면 할당
|
// 지붕면 할당
|
||||||
export function useRoofAllocationSetting(id) {
|
export function useRoofAllocationSetting(id) {
|
||||||
@ -81,12 +82,12 @@ export function useRoofAllocationSetting(id) {
|
|||||||
const [selectedRoofMaterial, setSelectedRoofMaterial] = useState(roofMaterials[0])
|
const [selectedRoofMaterial, setSelectedRoofMaterial] = useState(roofMaterials[0])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const roofBases = canvas.getObjects().filter((obj) => obj.name === 'roofBase')
|
const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||||
if (roofBases.length === 0) {
|
if (roofBases.length === 0) {
|
||||||
swalFire({ text: '할당할 지붕이 없습니다.' })
|
swalFire({ text: '할당할 지붕이 없습니다.' })
|
||||||
closePopup(id)
|
closePopup(id)
|
||||||
}
|
}
|
||||||
// if (type === 'roofBase') {
|
// if (type === POLYGON_TYPE.ROOF) {
|
||||||
// // 지붕면 할당
|
// // 지붕면 할당
|
||||||
//
|
//
|
||||||
// } else if ('roof') {
|
// } else if ('roof') {
|
||||||
@ -104,8 +105,8 @@ export function useRoofAllocationSetting(id) {
|
|||||||
|
|
||||||
// 선택한 지붕재로 할당
|
// 선택한 지붕재로 할당
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
const roofBases = canvas.getObjects().filter((obj) => obj.name === 'roofBase')
|
const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === 'wallLine')
|
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
||||||
roofBases.forEach((roofBase) => {
|
roofBases.forEach((roofBase) => {
|
||||||
try {
|
try {
|
||||||
splitPolygonWithLines(roofBase)
|
splitPolygonWithLines(roofBase)
|
||||||
@ -117,7 +118,7 @@ export function useRoofAllocationSetting(id) {
|
|||||||
canvas.remove(line)
|
canvas.remove(line)
|
||||||
})
|
})
|
||||||
|
|
||||||
canvas.remove(roofBase)
|
// canvas.remove(roofBase)
|
||||||
})
|
})
|
||||||
|
|
||||||
wallLines.forEach((wallLine) => {
|
wallLines.forEach((wallLine) => {
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { useEffect, useRef, useState } from 'react'
|
|||||||
import { useLine } from '@/hooks/useLine'
|
import { useLine } from '@/hooks/useLine'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useEvent } from '@/hooks/useEvent'
|
import { useEvent } from '@/hooks/useEvent'
|
||||||
import { LINE_TYPE } from '@/common/common'
|
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
|
||||||
import { useMode } from '@/hooks/useMode'
|
import { useMode } from '@/hooks/useMode'
|
||||||
import { usePolygon } from '@/hooks/usePolygon'
|
import { usePolygon } from '@/hooks/usePolygon'
|
||||||
import { outerLineFixState } from '@/store/outerLineAtom'
|
import { outerLineFixState } from '@/store/outerLineAtom'
|
||||||
@ -60,7 +60,7 @@ export function useRoofShapePassivitySetting(id) {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isLoading) return
|
if (!isLoading) return
|
||||||
addCanvasMouseEventListener('mouse:down', mouseDown)
|
addCanvasMouseEventListener('mouse:down', mouseDown)
|
||||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === 'wallLine')
|
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
||||||
|
|
||||||
canvas?.remove(...wallLines)
|
canvas?.remove(...wallLines)
|
||||||
|
|
||||||
@ -185,7 +185,7 @@ export function useRoofShapePassivitySetting(id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleLineToPolygon = () => {
|
const handleLineToPolygon = () => {
|
||||||
const roofBases = canvas.getObjects().filter((obj) => obj.name === 'roofBase')
|
const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||||
const exceptObjs = canvas.getObjects().filter((obj) => obj.name !== 'outerLine' && obj.parent?.name !== 'outerLine')
|
const exceptObjs = canvas.getObjects().filter((obj) => obj.name !== 'outerLine' && obj.parent?.name !== 'outerLine')
|
||||||
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||||
exceptObjs.forEach((obj) => {
|
exceptObjs.forEach((obj) => {
|
||||||
@ -199,10 +199,10 @@ export function useRoofShapePassivitySetting(id) {
|
|||||||
let wall
|
let wall
|
||||||
|
|
||||||
if (isFix.current) {
|
if (isFix.current) {
|
||||||
wall = addPolygonByLines(lines, { name: 'wallLine', fill: 'transparent', stroke: 'black' })
|
wall = addPolygonByLines(lines, { name: POLYGON_TYPE.WALL, fill: 'transparent', stroke: 'black' })
|
||||||
} else {
|
} else {
|
||||||
// 그냥 닫을 경우 처리
|
// 그냥 닫을 경우 처리
|
||||||
wall = addPolygonByLines([...initLines.current], { name: 'wallLine', fill: 'transparent', stroke: 'black' })
|
wall = addPolygonByLines([...initLines.current], { name: POLYGON_TYPE.WALL, fill: 'transparent', stroke: 'black' })
|
||||||
lines.forEach((line, idx) => {
|
lines.forEach((line, idx) => {
|
||||||
line.attributes = initLines.current[idx].attributes
|
line.attributes = initLines.current[idx].attributes
|
||||||
})
|
})
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { useEffect, useRef, useState } from 'react'
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useRecoilValue, useSetRecoilState } from 'recoil'
|
import { useRecoilValue, useSetRecoilState } from 'recoil'
|
||||||
import { ANGLE_TYPE, canvasState, currentAngleTypeSelector, currentMenuState, currentObjectState, pitchTextSelector } from '@/store/canvasAtom'
|
import { ANGLE_TYPE, canvasState, currentAngleTypeSelector, currentMenuState, currentObjectState, pitchTextSelector } from '@/store/canvasAtom'
|
||||||
import { LINE_TYPE } from '@/common/common'
|
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
|
||||||
import { usePolygon } from '@/hooks/usePolygon'
|
import { usePolygon } from '@/hooks/usePolygon'
|
||||||
import { useMode } from '@/hooks/useMode'
|
import { useMode } from '@/hooks/useMode'
|
||||||
import { useLine } from '@/hooks/useLine'
|
import { useLine } from '@/hooks/useLine'
|
||||||
@ -129,7 +129,7 @@ export function useRoofShapeSetting(id) {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (shapeNum === 4) {
|
if (shapeNum === 4) {
|
||||||
canvas?.remove(canvas.getObjects().find((obj) => obj.name === 'wallLine'))
|
canvas?.remove(canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.WALL))
|
||||||
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||||
outerLines.forEach((line) => {
|
outerLines.forEach((line) => {
|
||||||
showLine(line)
|
showLine(line)
|
||||||
@ -376,20 +376,20 @@ export function useRoofShapeSetting(id) {
|
|||||||
// 기존 wallLine, roofBase 제거
|
// 기존 wallLine, roofBase 제거
|
||||||
canvas
|
canvas
|
||||||
.getObjects()
|
.getObjects()
|
||||||
.filter((obj) => obj.name === 'wallLine')
|
.filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
||||||
.forEach((line) => {
|
.forEach((line) => {
|
||||||
canvas.remove(line)
|
canvas.remove(line)
|
||||||
})
|
})
|
||||||
|
|
||||||
canvas
|
canvas
|
||||||
.getObjects()
|
.getObjects()
|
||||||
.filter((obj) => obj.name === 'roofBase')
|
.filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||||
.forEach((obj) => {
|
.forEach((obj) => {
|
||||||
canvas.remove(...obj.innerLines)
|
canvas.remove(...obj.innerLines)
|
||||||
canvas.remove(obj)
|
canvas.remove(obj)
|
||||||
})
|
})
|
||||||
|
|
||||||
const polygon = addPolygonByLines(outerLines, { name: 'wallLine' })
|
const polygon = addPolygonByLines(outerLines, { name: POLYGON_TYPE.WALL })
|
||||||
polygon.lines = [...outerLines]
|
polygon.lines = [...outerLines]
|
||||||
|
|
||||||
addPitchTextsByOuterLines()
|
addPitchTextsByOuterLines()
|
||||||
|
|||||||
@ -5,7 +5,7 @@ export const settingModalFirstOptionsState = atom({
|
|||||||
default: {
|
default: {
|
||||||
option1: [
|
option1: [
|
||||||
{ id: 1, column: 'allocDisplay', name: 'modal.canvas.setting.first.option.alloc', selected: false },
|
{ id: 1, column: 'allocDisplay', name: 'modal.canvas.setting.first.option.alloc', selected: false },
|
||||||
{ id: 2, column: 'outlineDisplay', name: 'modal.canvas.setting.first.option.outline', selected: false },
|
{ id: 2, column: 'outlineDisplay', name: 'modal.canvas.setting.first.option.outline', selected: true },
|
||||||
{ id: 3, column: 'gridDisplay', name: 'modal.canvas.setting.first.option.grid', selected: false },
|
{ id: 3, column: 'gridDisplay', name: 'modal.canvas.setting.first.option.grid', selected: false },
|
||||||
{ id: 4, column: 'lineDisplay', name: 'modal.canvas.setting.first.option.roof.line', selected: false },
|
{ id: 4, column: 'lineDisplay', name: 'modal.canvas.setting.first.option.roof.line', selected: false },
|
||||||
{ id: 5, column: 'wordDisplay', name: 'modal.canvas.setting.first.option.word', selected: false },
|
{ id: 5, column: 'wordDisplay', name: 'modal.canvas.setting.first.option.word', selected: false },
|
||||||
|
|||||||
@ -521,9 +521,11 @@ export function isPointOnLine(line, point) {
|
|||||||
const a = line.y2 - line.y1
|
const a = line.y2 - line.y1
|
||||||
const b = line.x1 - line.x2
|
const b = line.x1 - line.x2
|
||||||
const c = line.x2 * line.y1 - line.x1 * line.y2
|
const c = line.x2 * line.y1 - line.x1 * line.y2
|
||||||
return a * point.x + b * point.y + c === 0
|
const result = Math.abs(a * point.x + b * point.y + c) / 100
|
||||||
}
|
|
||||||
|
|
||||||
|
// 점이 선 위에 있는지 확인
|
||||||
|
return result <= 10
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 점과 가까운 line 찾기
|
* 점과 가까운 line 찾기
|
||||||
* @param point
|
* @param point
|
||||||
|
|||||||
@ -1,6 +1,14 @@
|
|||||||
import { fabric } from 'fabric'
|
import { fabric } from 'fabric'
|
||||||
import { QLine } from '@/components/fabric/QLine'
|
import { QLine } from '@/components/fabric/QLine'
|
||||||
import { calculateIntersection, distanceBetweenPoints, findClosestPoint, getDegreeByChon, getDirectionByPoint } from '@/util/canvas-util'
|
import {
|
||||||
|
calculateIntersection,
|
||||||
|
distanceBetweenPoints,
|
||||||
|
findClosestPoint,
|
||||||
|
getDegreeByChon,
|
||||||
|
getDirectionByPoint,
|
||||||
|
isPointOnLine,
|
||||||
|
} from '@/util/canvas-util'
|
||||||
|
|
||||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||||
import * as turf from '@turf/turf'
|
import * as turf from '@turf/turf'
|
||||||
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
|
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
|
||||||
@ -957,10 +965,13 @@ export default function offsetPolygon(vertices, offset) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const splitPolygonWithLines = (polygon) => {
|
/*export const splitPolygonWithLines = (polygon) => {
|
||||||
const roofs = []
|
const roofs = []
|
||||||
const allLines = [...polygon.innerLines]
|
const allLines = [...polygon.innerLines]
|
||||||
|
|
||||||
|
const polygonLines = polygon.lines
|
||||||
|
const innerLines = polygon.innerLines
|
||||||
|
|
||||||
allLines.forEach((line) => {
|
allLines.forEach((line) => {
|
||||||
line.startPoint = { x: line.x1, y: line.y1 }
|
line.startPoint = { x: line.x1, y: line.y1 }
|
||||||
line.endPoint = { x: line.x2, y: line.y2 }
|
line.endPoint = { x: line.x2, y: line.y2 }
|
||||||
@ -983,10 +994,10 @@ export const splitPolygonWithLines = (polygon) => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/!**
|
||||||
* 좌표 테스트용
|
* 좌표 테스트용
|
||||||
*/
|
*!/
|
||||||
/*allLines.forEach((line) => {
|
/!*allLines.forEach((line) => {
|
||||||
const text = new fabric.Text(`(${line.startPoint.x},${line.startPoint.y})`, {
|
const text = new fabric.Text(`(${line.startPoint.x},${line.startPoint.y})`, {
|
||||||
left: line.startPoint.x,
|
left: line.startPoint.x,
|
||||||
top: line.startPoint.y,
|
top: line.startPoint.y,
|
||||||
@ -1015,10 +1026,10 @@ export const splitPolygonWithLines = (polygon) => {
|
|||||||
|
|
||||||
polygon.canvas.add(text)
|
polygon.canvas.add(text)
|
||||||
polygon.canvas.renderAll()
|
polygon.canvas.renderAll()
|
||||||
})*/
|
})*!/
|
||||||
/**
|
/!**
|
||||||
* 좌표 테스트용 끝
|
* 좌표 테스트용 끝
|
||||||
*/
|
*!/
|
||||||
|
|
||||||
polygon.points.forEach((point, index) => {
|
polygon.points.forEach((point, index) => {
|
||||||
allLines.forEach((line) => {
|
allLines.forEach((line) => {
|
||||||
@ -1164,6 +1175,233 @@ export const splitPolygonWithLines = (polygon) => {
|
|||||||
polygon.canvas.add(roof)
|
polygon.canvas.add(roof)
|
||||||
polygon.canvas.renderAll()
|
polygon.canvas.renderAll()
|
||||||
})
|
})
|
||||||
|
}*/
|
||||||
|
export const splitPolygonWithLines = (polygon) => {
|
||||||
|
const canvas = polygon.canvas
|
||||||
|
polygon.set({ visible: false })
|
||||||
|
let innerLines = [...polygon.innerLines]
|
||||||
|
let polygonLines = [...polygon.lines]
|
||||||
|
const roofs = []
|
||||||
|
|
||||||
|
let delIndexs = []
|
||||||
|
let newLines = []
|
||||||
|
|
||||||
|
polygonLines.forEach((line, index) => {
|
||||||
|
line.tempIndex = index
|
||||||
|
innerLines.forEach((innerLine) => {
|
||||||
|
let newLine1, newLine2
|
||||||
|
if (isPointOnLine(line, innerLine.startPoint)) {
|
||||||
|
// 해당 line을 startPoint로 나눈 line2개를 canvas에 추가 하고 기존 line을 제거한다.
|
||||||
|
newLine1 = new QLine([line.x1, line.y1, innerLine.startPoint.x, innerLine.startPoint.y], {
|
||||||
|
fontSize: polygon.fontSize,
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 3,
|
||||||
|
})
|
||||||
|
|
||||||
|
newLine2 = new QLine([innerLine.startPoint.x, innerLine.startPoint.y, line.x2, line.y2], {
|
||||||
|
fontSize: polygon.fontSize,
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 3,
|
||||||
|
})
|
||||||
|
delIndexs.push(polygonLines.indexOf(line))
|
||||||
|
canvas.remove(polygonLines[polygonLines.indexOf(line)])
|
||||||
|
if (newLine1.length / 10 > 10) {
|
||||||
|
newLines.push(newLine1)
|
||||||
|
}
|
||||||
|
if (newLine2.length / 10 > 10) {
|
||||||
|
newLines.push(newLine2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isPointOnLine(line, innerLine.endPoint)) {
|
||||||
|
newLine1 = new QLine([line.x1, line.y1, innerLine.endPoint.x, innerLine.endPoint.y], {
|
||||||
|
fontSize: polygon.fontSize,
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 3,
|
||||||
|
})
|
||||||
|
|
||||||
|
newLine2 = new QLine([innerLine.endPoint.x, innerLine.endPoint.y, line.x2, line.y2], {
|
||||||
|
fontSize: polygon.fontSize,
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 3,
|
||||||
|
})
|
||||||
|
delIndexs.push(polygonLines.indexOf(line))
|
||||||
|
canvas.remove(polygonLines[polygonLines.indexOf(line)])
|
||||||
|
if (newLine1.length / 10 > 10) {
|
||||||
|
newLines.push(newLine1)
|
||||||
|
}
|
||||||
|
if (newLine2.length / 10 > 10) {
|
||||||
|
newLines.push(newLine2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
polygonLines = polygonLines.filter((line) => !delIndexs.includes(line.tempIndex))
|
||||||
|
polygonLines = [...polygonLines, ...newLines]
|
||||||
|
|
||||||
|
const allLines = [...polygonLines, ...innerLines]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 왼쪽 상단을 startPoint로 전부 변경
|
||||||
|
*/
|
||||||
|
allLines.forEach((line) => {
|
||||||
|
let startPoint // 시작점
|
||||||
|
let endPoint // 끝점
|
||||||
|
if (line.x1 < line.x2) {
|
||||||
|
startPoint = { x: line.x1, y: line.y1 }
|
||||||
|
endPoint = { x: line.x2, y: line.y2 }
|
||||||
|
} else if (line.x1 > line.x2) {
|
||||||
|
startPoint = { x: line.x2, y: line.y2 }
|
||||||
|
endPoint = { x: line.x1, y: line.y1 }
|
||||||
|
} else {
|
||||||
|
if (line.y1 < line.y2) {
|
||||||
|
startPoint = { x: line.x1, y: line.y1 }
|
||||||
|
endPoint = { x: line.x2, y: line.y2 }
|
||||||
|
} else {
|
||||||
|
startPoint = { x: line.x2, y: line.y2 }
|
||||||
|
endPoint = { x: line.x1, y: line.y1 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
line.startPoint = startPoint
|
||||||
|
line.endPoint = endPoint
|
||||||
|
})
|
||||||
|
|
||||||
|
polygonLines.forEach((line) => {
|
||||||
|
const startPoint = line.startPoint // 시작점
|
||||||
|
let arrivalPoint = line.endPoint // 도착점
|
||||||
|
|
||||||
|
let currentPoint = startPoint
|
||||||
|
const roofPoints = [startPoint]
|
||||||
|
|
||||||
|
const startLine = line
|
||||||
|
const visitPoints = [startPoint]
|
||||||
|
const visitLines = [startLine]
|
||||||
|
let cnt = 0
|
||||||
|
|
||||||
|
while (!isSamePoint(currentPoint, arrivalPoint)) {
|
||||||
|
line.set({ stroke: 'red' })
|
||||||
|
canvas.renderAll()
|
||||||
|
let nextLines = allLines.filter(
|
||||||
|
(line2) =>
|
||||||
|
(isSamePoint(line2.startPoint, currentPoint) || isSamePoint(line2.endPoint, currentPoint)) &&
|
||||||
|
line !== line2 &&
|
||||||
|
innerLines.includes(line2) &&
|
||||||
|
!visitLines.includes(line2),
|
||||||
|
)
|
||||||
|
|
||||||
|
if (nextLines.length === 0) {
|
||||||
|
nextLines = allLines.filter(
|
||||||
|
(line2) =>
|
||||||
|
(isSamePoint(line2.startPoint, currentPoint) || isSamePoint(line2.endPoint, currentPoint)) &&
|
||||||
|
line !== line2 &&
|
||||||
|
!visitLines.includes(line2),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nextLines) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
let comparisonPoints = []
|
||||||
|
|
||||||
|
nextLines.forEach((nextLine) => {
|
||||||
|
if (isSamePoint(nextLine.startPoint, currentPoint)) {
|
||||||
|
comparisonPoints.push(nextLine.endPoint)
|
||||||
|
} else {
|
||||||
|
comparisonPoints.push(nextLine.startPoint)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
comparisonPoints = comparisonPoints.filter((point) => !visitPoints.some((visitPoint) => isSamePoint(visitPoint, point)))
|
||||||
|
comparisonPoints = comparisonPoints.filter((point) => !isSamePoint(point, currentPoint))
|
||||||
|
|
||||||
|
const minDistancePoint = comparisonPoints.reduce((prev, current) => {
|
||||||
|
const prevDistance = Math.sqrt(Math.pow(prev.x - arrivalPoint.x, 2) + Math.pow(prev.y - arrivalPoint.y, 2))
|
||||||
|
const currentDistance = Math.sqrt(Math.pow(current.x - arrivalPoint.x, 2) + Math.pow(current.y - arrivalPoint.y, 2))
|
||||||
|
|
||||||
|
return prevDistance < currentDistance ? prev : current
|
||||||
|
}, comparisonPoints[0])
|
||||||
|
|
||||||
|
nextLines.forEach((nextLine) => {
|
||||||
|
if (isSamePoint(nextLine.startPoint, minDistancePoint) || isSamePoint(nextLine.endPoint, minDistancePoint)) {
|
||||||
|
visitLines.push(nextLine)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
currentPoint = { ...minDistancePoint }
|
||||||
|
roofPoints.push(currentPoint)
|
||||||
|
cnt++
|
||||||
|
if (cnt > 100) {
|
||||||
|
throw new Error('무한루프')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
roofs.push(roofPoints)
|
||||||
|
})
|
||||||
|
|
||||||
|
const newRoofs = removeDuplicatePolygons(roofs)
|
||||||
|
console.log(newRoofs)
|
||||||
|
newRoofs.forEach((roofPoint, index) => {
|
||||||
|
let defense, pitch
|
||||||
|
const direction = getDirectionByPoint(roofPoint[0], roofPoint[roofPoint.length - 1])
|
||||||
|
|
||||||
|
switch (direction) {
|
||||||
|
case 'top':
|
||||||
|
defense = 'east'
|
||||||
|
break
|
||||||
|
case 'right':
|
||||||
|
defense = 'south'
|
||||||
|
break
|
||||||
|
case 'bottom':
|
||||||
|
defense = 'west'
|
||||||
|
break
|
||||||
|
case 'left':
|
||||||
|
defense = 'north'
|
||||||
|
break
|
||||||
|
}
|
||||||
|
pitch = polygon.lines[index].attributes?.pitch ?? 0
|
||||||
|
|
||||||
|
const roof = new QPolygon(roofPoint, {
|
||||||
|
fontSize: polygon.fontSize,
|
||||||
|
stroke: 'black',
|
||||||
|
fill: 'transparent',
|
||||||
|
strokeWidth: 3,
|
||||||
|
name: POLYGON_TYPE.ROOF,
|
||||||
|
originX: 'center',
|
||||||
|
originY: 'center',
|
||||||
|
selectable: true,
|
||||||
|
defense: defense,
|
||||||
|
direction: defense,
|
||||||
|
pitch: pitch,
|
||||||
|
})
|
||||||
|
|
||||||
|
polygon.canvas.add(roof)
|
||||||
|
canvas.remove(polygon)
|
||||||
|
polygon.canvas.renderAll()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const removeDuplicatePolygons = (polygons) => {
|
||||||
|
const uniquePolygons = []
|
||||||
|
|
||||||
|
polygons.forEach((polygon) => {
|
||||||
|
const sortedPolygon = polygon
|
||||||
|
.map((point) => `${Math.floor(point.x)},${Math.floor(point.y)}`)
|
||||||
|
.sort()
|
||||||
|
.join('|')
|
||||||
|
const isDuplicate = uniquePolygons.some((uniquePolygon) => {
|
||||||
|
const sortedUniquePolygon = uniquePolygon
|
||||||
|
.map((point) => `${Math.floor(point.x)},${Math.floor(point.y)}`)
|
||||||
|
.sort()
|
||||||
|
.join('|')
|
||||||
|
return sortedPolygon === sortedUniquePolygon
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!isDuplicate) {
|
||||||
|
uniquePolygons.push(polygon)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return uniquePolygons
|
||||||
}
|
}
|
||||||
|
|
||||||
const isSamePoint = (a, b) => {
|
const isSamePoint = (a, b) => {
|
||||||
@ -1218,6 +1456,7 @@ export const drawRidgeRoof = (roofId, canvas) => {
|
|||||||
* @param canvas
|
* @param canvas
|
||||||
*/
|
*/
|
||||||
const drawRidge = (roof, canvas) => {
|
const drawRidge = (roof, canvas) => {
|
||||||
|
debugger
|
||||||
const wallLines = canvas?.getObjects().find((object) => object.name === POLYGON_TYPE.WALL && object.attributes.roofId === roof.id).lines // 외벽의 라인
|
const wallLines = canvas?.getObjects().find((object) => object.name === POLYGON_TYPE.WALL && object.attributes.roofId === roof.id).lines // 외벽의 라인
|
||||||
const roofLines = roof.lines // 지붕의 라인
|
const roofLines = roof.lines // 지붕의 라인
|
||||||
let ridgeRoof = []
|
let ridgeRoof = []
|
||||||
@ -3312,7 +3551,7 @@ function createRoofPaddingPolygon(polygon, lines, arcSegments = 0) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function arePointsEqual(point1, point2) {
|
function arePointsEqual(point1, point2) {
|
||||||
return point1.x === point2.x && point1.y === point2.y
|
return Math.abs(point1.x - point2.x) < 1 && Math.abs(point1.y - point2.y) - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
function arraysHaveSamePoints(array1, array2) {
|
function arraysHaveSamePoints(array1, array2) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user