Compare commits
No commits in common. "acde55f4d134175ee2910b16d32e065fe1dfd3d8" and "3c92c2b8d7a462971e6abeb5b21b22aa8557112e" have entirely different histories.
acde55f4d1
...
3c92c2b8d7
1
.gitignore
vendored
1
.gitignore
vendored
@ -43,4 +43,3 @@ yarn.lock
|
|||||||
package-lock.json
|
package-lock.json
|
||||||
pnpm-lock.yaml
|
pnpm-lock.yaml
|
||||||
certificates
|
certificates
|
||||||
.ai
|
|
||||||
@ -22,7 +22,7 @@
|
|||||||
"chart.js": "^4.4.6",
|
"chart.js": "^4.4.6",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"env-cmd": "^10.1.0",
|
"env-cmd": "^10.1.0",
|
||||||
"fabric": "^5.5.2",
|
"fabric": "^5.3.0",
|
||||||
"framer-motion": "^11.2.13",
|
"framer-motion": "^11.2.13",
|
||||||
"fs": "^0.0.1-security",
|
"fs": "^0.0.1-security",
|
||||||
"iron-session": "^8.0.2",
|
"iron-session": "^8.0.2",
|
||||||
|
|||||||
@ -219,8 +219,7 @@ export const SAVE_KEY = [
|
|||||||
'originWidth',
|
'originWidth',
|
||||||
'originHeight',
|
'originHeight',
|
||||||
'skeletonLines',
|
'skeletonLines',
|
||||||
'skeleton',
|
'skeleton'
|
||||||
'viewportTransform',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype, fabric.Group.prototype]
|
export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype, fabric.Group.prototype]
|
||||||
|
|||||||
@ -336,8 +336,8 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
|||||||
if (types.every((type) => type === LINE_TYPE.WALLLINE.EAVES)) {
|
if (types.every((type) => type === LINE_TYPE.WALLLINE.EAVES)) {
|
||||||
// 용마루 -- straight-skeleton
|
// 용마루 -- straight-skeleton
|
||||||
console.log('용마루 지붕')
|
console.log('용마루 지붕')
|
||||||
//drawRidgeRoof(this.id, this.canvas, textMode)
|
drawRidgeRoof(this.id, this.canvas, textMode)
|
||||||
drawSkeletonRidgeRoof(this.id, this.canvas, textMode);
|
//drawSkeletonRidgeRoof(this.id, this.canvas, textMode);
|
||||||
} else if (isGableRoof(types)) {
|
} else if (isGableRoof(types)) {
|
||||||
// A형, B형 박공 지붕
|
// A형, B형 박공 지붕
|
||||||
console.log('패턴 지붕')
|
console.log('패턴 지붕')
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { useContext, useEffect, useRef } from 'react'
|
import { useContext, useEffect, useRef } from 'react'
|
||||||
|
|
||||||
import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil'
|
import { useRecoilValue, useResetRecoilState } from 'recoil'
|
||||||
|
|
||||||
import QContextMenu from '@/components/common/context-menu/QContextMenu'
|
import QContextMenu from '@/components/common/context-menu/QContextMenu'
|
||||||
import PanelBatchStatistics from '@/components/floor-plan/modal/panelBatch/PanelBatchStatistics'
|
import PanelBatchStatistics from '@/components/floor-plan/modal/panelBatch/PanelBatchStatistics'
|
||||||
@ -11,7 +11,7 @@ import { useCanvas } from '@/hooks/useCanvas'
|
|||||||
import { usePlan } from '@/hooks/usePlan'
|
import { usePlan } from '@/hooks/usePlan'
|
||||||
import { useContextMenu } from '@/hooks/useContextMenu'
|
import { useContextMenu } from '@/hooks/useContextMenu'
|
||||||
import { useCanvasConfigInitialize } from '@/hooks/common/useCanvasConfigInitialize'
|
import { useCanvasConfigInitialize } from '@/hooks/common/useCanvasConfigInitialize'
|
||||||
import { canvasZoomState, currentMenuState } from '@/store/canvasAtom'
|
import { currentMenuState } from '@/store/canvasAtom'
|
||||||
import { totalDisplaySelector } from '@/store/settingAtom'
|
import { totalDisplaySelector } from '@/store/settingAtom'
|
||||||
import { POLYGON_TYPE } from '@/common/common'
|
import { POLYGON_TYPE } from '@/common/common'
|
||||||
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
|
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
|
||||||
@ -50,7 +50,6 @@ export default function CanvasFrame() {
|
|||||||
const resetSeriesState = useResetRecoilState(seriesState)
|
const resetSeriesState = useResetRecoilState(seriesState)
|
||||||
const resetModelsState = useResetRecoilState(modelsState)
|
const resetModelsState = useResetRecoilState(modelsState)
|
||||||
const resetCompasDeg = useResetRecoilState(compasDegAtom)
|
const resetCompasDeg = useResetRecoilState(compasDegAtom)
|
||||||
const [zoom, setCanvasZoom] = useRecoilState(canvasZoomState)
|
|
||||||
const resetSelectedModelsState = useResetRecoilState(selectedModelsState)
|
const resetSelectedModelsState = useResetRecoilState(selectedModelsState)
|
||||||
const resetPcsCheckState = useResetRecoilState(pcsCheckState)
|
const resetPcsCheckState = useResetRecoilState(pcsCheckState)
|
||||||
const { handleModuleSelectionTotal } = useCanvasPopupStatusController()
|
const { handleModuleSelectionTotal } = useCanvasPopupStatusController()
|
||||||
@ -68,13 +67,6 @@ export default function CanvasFrame() {
|
|||||||
canvasLoadInit() //config된 상태로 캔버스 객체를 그린다
|
canvasLoadInit() //config된 상태로 캔버스 객체를 그린다
|
||||||
canvas?.renderAll() // 캔버스를 다시 그립니다.
|
canvas?.renderAll() // 캔버스를 다시 그립니다.
|
||||||
|
|
||||||
if (canvas.viewportTransform) {
|
|
||||||
if (canvas.viewportTransform[0] !== 1) {
|
|
||||||
setCanvasZoom(Number((canvas.viewportTransform[0] * 100).toFixed(0)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
canvas.originViewPortTransform = canvas.viewportTransform
|
|
||||||
|
|
||||||
if (canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE).length > 0) {
|
if (canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE).length > 0) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setSelectedMenu('module')
|
setSelectedMenu('module')
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { useContext, useEffect, useState } from 'react'
|
import { useContext, useEffect, useState } from 'react'
|
||||||
|
|
||||||
import { usePathname, useRouter } from 'next/navigation'
|
import { usePathname, useRouter, useSearchParams } from 'next/navigation'
|
||||||
|
|
||||||
import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil'
|
import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil'
|
||||||
|
|
||||||
@ -25,18 +25,17 @@ import { useCommonUtils } from '@/hooks/common/useCommonUtils'
|
|||||||
import useMenu from '@/hooks/common/useMenu'
|
import useMenu from '@/hooks/common/useMenu'
|
||||||
import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController'
|
import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController'
|
||||||
import { useAxios } from '@/hooks/useAxios'
|
import { useAxios } from '@/hooks/useAxios'
|
||||||
import {
|
import { canvasSettingState, canvasState, canvasZoomState, currentMenuState, verticalHorizontalModeState, currentCanvasPlanState } from '@/store/canvasAtom'
|
||||||
canvasSettingState,
|
|
||||||
canvasState,
|
|
||||||
canvasZoomState,
|
|
||||||
currentCanvasPlanState,
|
|
||||||
currentMenuState,
|
|
||||||
verticalHorizontalModeState,
|
|
||||||
} from '@/store/canvasAtom'
|
|
||||||
import { sessionStore } from '@/store/commonAtom'
|
import { sessionStore } from '@/store/commonAtom'
|
||||||
import { outerLinePointsState } from '@/store/outerLineAtom'
|
import { outerLinePointsState } from '@/store/outerLineAtom'
|
||||||
import { appMessageStore, globalLocaleStore } from '@/store/localeAtom'
|
import { appMessageStore, globalLocaleStore } from '@/store/localeAtom'
|
||||||
import { addedRoofsState, basicSettingState, selectedRoofMaterialSelector, settingModalFirstOptionsState } from '@/store/settingAtom'
|
import {
|
||||||
|
addedRoofsState,
|
||||||
|
basicSettingState,
|
||||||
|
corridorDimensionSelector,
|
||||||
|
selectedRoofMaterialSelector,
|
||||||
|
settingModalFirstOptionsState,
|
||||||
|
} from '@/store/settingAtom'
|
||||||
import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom'
|
import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom'
|
||||||
import { commonUtilsState } from '@/store/commonUtilsAtom'
|
import { commonUtilsState } from '@/store/commonUtilsAtom'
|
||||||
import { menusState } from '@/store/menuAtom'
|
import { menusState } from '@/store/menuAtom'
|
||||||
@ -52,7 +51,6 @@ import { QcastContext } from '@/app/QcastProvider'
|
|||||||
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
||||||
import { usePolygon } from '@/hooks/usePolygon'
|
import { usePolygon } from '@/hooks/usePolygon'
|
||||||
import { useTrestle } from '@/hooks/module/useTrestle'
|
import { useTrestle } from '@/hooks/module/useTrestle'
|
||||||
|
|
||||||
export default function CanvasMenu(props) {
|
export default function CanvasMenu(props) {
|
||||||
const [currentCanvasPlan, setCurrentCanvasPlan] = useRecoilState(currentCanvasPlanState)
|
const [currentCanvasPlan, setCurrentCanvasPlan] = useRecoilState(currentCanvasPlanState)
|
||||||
const { selectedMenu, setSelectedMenu } = props
|
const { selectedMenu, setSelectedMenu } = props
|
||||||
@ -517,10 +515,7 @@ export default function CanvasMenu(props) {
|
|||||||
if (createUser === 'T01' && sessionState.storeId !== 'T01') {
|
if (createUser === 'T01' && sessionState.storeId !== 'T01') {
|
||||||
setAllButtonStyles('none')
|
setAllButtonStyles('none')
|
||||||
} else {
|
} else {
|
||||||
setEstimateContextState({
|
setEstimateContextState({ tempFlg: estimateRecoilState.tempFlg, lockFlg: estimateRecoilState.lockFlg })
|
||||||
tempFlg: estimateRecoilState.tempFlg,
|
|
||||||
lockFlg: estimateRecoilState.lockFlg,
|
|
||||||
})
|
|
||||||
handleButtonStyles(estimateRecoilState.tempFlg, estimateRecoilState.lockFlg, estimateContextState.docNo)
|
handleButtonStyles(estimateRecoilState.tempFlg, estimateRecoilState.lockFlg, estimateContextState.docNo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -227,33 +227,11 @@ export default function CircuitTrestleSetting({ id }) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const isMultiModule = selectedModules.itemList.length > 1
|
|
||||||
|
|
||||||
let isAllIndfcs = false
|
|
||||||
|
|
||||||
if (isMultiModule) {
|
|
||||||
//INDFCS 실내집중, OUTDMULTI 옥외멀티
|
|
||||||
// 1. 모듈이 혼합형일 경우 선택한 pcs가 실내집중인 경우 alert
|
|
||||||
if (selectedModels.length > 0) {
|
|
||||||
isAllIndfcs = selectedModels.every((model) => model.pcsTpCd === 'INDFCS')
|
|
||||||
} else {
|
|
||||||
isAllIndfcs = models.every((model) => model.pcsTpCd === 'INDFCS')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isAllIndfcs) {
|
|
||||||
swalFire({
|
|
||||||
title: getMessage('module.circuit.indoor.focused.error'),
|
|
||||||
type: 'alert',
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
...getOptYn(),
|
...getOptYn(),
|
||||||
useModuleItemList: getUseModuleItemList(),
|
useModuleItemList: getUseModuleItemList(),
|
||||||
roofSurfaceList: getRoofSurfaceList(),
|
roofSurfaceList: getRoofSurfaceList(),
|
||||||
pcsItemList: getPcsItemList(isMultiModule),
|
pcsItemList: getPcsItemList(),
|
||||||
}
|
}
|
||||||
|
|
||||||
// 파워컨디셔너 추천 목록 조회
|
// 파워컨디셔너 추천 목록 조회
|
||||||
@ -314,12 +292,12 @@ export default function CircuitTrestleSetting({ id }) {
|
|||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// 회로 구성 가능 여부 체크
|
// 회로 구성 가능 여부 체크
|
||||||
getPcsVoltageChk({ ...params, pcsItemList: getSelectedPcsItemList(isMultiModule) }).then((res) => {
|
getPcsVoltageChk({ ...params, pcsItemList: getSelectedPcsItemList() }).then((res) => {
|
||||||
if (res.resultCode === 'S') {
|
if (res.resultCode === 'S') {
|
||||||
// 회로 구성 가능 여부 체크 통과 시 승압설정 정보 조회
|
// 회로 구성 가능 여부 체크 통과 시 승압설정 정보 조회
|
||||||
getPcsVoltageStepUpList({
|
getPcsVoltageStepUpList({
|
||||||
...params,
|
...params,
|
||||||
pcsItemList: getSelectedPcsItemList(isMultiModule),
|
pcsItemList: getSelectedPcsItemList(),
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
if (res?.result.resultCode === 'S' && res?.data) {
|
if (res?.result.resultCode === 'S' && res?.data) {
|
||||||
setTabNum(2)
|
setTabNum(2)
|
||||||
@ -545,7 +523,6 @@ export default function CircuitTrestleSetting({ id }) {
|
|||||||
obj.circuit = null
|
obj.circuit = null
|
||||||
obj.pcsItemId = null
|
obj.pcsItemId = null
|
||||||
obj.circuitNumber = null
|
obj.circuitNumber = null
|
||||||
obj.pcs = null
|
|
||||||
})
|
})
|
||||||
setSelectedModels(
|
setSelectedModels(
|
||||||
JSON.parse(JSON.stringify(selectedModels)).map((model) => {
|
JSON.parse(JSON.stringify(selectedModels)).map((model) => {
|
||||||
|
|||||||
@ -649,13 +649,7 @@ export default function StepUp(props) {
|
|||||||
style={{ cursor: allocationType === 'auto' ? 'pointer' : 'default' }}
|
style={{ cursor: allocationType === 'auto' ? 'pointer' : 'default' }}
|
||||||
>
|
>
|
||||||
<td className="al-r">{item.serQty}</td>
|
<td className="al-r">{item.serQty}</td>
|
||||||
<td className="al-r">
|
<td className="al-r">{item.paralQty}</td>
|
||||||
{/* 2025.12.04 select 추가 */}
|
|
||||||
<select className="select-light dark table-select" name="" id="">
|
|
||||||
<option value="">{item.paralQty}</option>
|
|
||||||
</select>
|
|
||||||
</td>
|
|
||||||
{/* <td className="al-r">{item.paralQty}</td> */}
|
|
||||||
</tr>
|
</tr>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import { moduleStatisticsState } from '@/store/circuitTrestleAtom'
|
|||||||
import { fontSelector } from '@/store/fontAtom'
|
import { fontSelector } from '@/store/fontAtom'
|
||||||
import { selectedModuleState } from '@/store/selectedModuleOptions'
|
import { selectedModuleState } from '@/store/selectedModuleOptions'
|
||||||
import { circuitNumDisplaySelector } from '@/store/settingAtom'
|
import { circuitNumDisplaySelector } from '@/store/settingAtom'
|
||||||
import { useContext, useEffect, useRef, useState } from 'react'
|
import { useContext, useEffect, useState } from 'react'
|
||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
import { normalizeDigits } from '@/util/input-utils'
|
import { normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
@ -32,7 +32,6 @@ export default function PassivityCircuitAllocation(props) {
|
|||||||
const { header, rows, footer } = useRecoilValue(moduleStatisticsState)
|
const { header, rows, footer } = useRecoilValue(moduleStatisticsState)
|
||||||
const [circuitNumber, setCircuitNumber] = useState(1)
|
const [circuitNumber, setCircuitNumber] = useState(1)
|
||||||
const [targetModules, setTargetModules] = useState([])
|
const [targetModules, setTargetModules] = useState([])
|
||||||
const targetModulesRef = useRef([])
|
|
||||||
const { getPcsManualConfChk } = useMasterController()
|
const { getPcsManualConfChk } = useMasterController()
|
||||||
const isDisplayCircuitNumber = useRecoilValue(circuitNumDisplaySelector)
|
const isDisplayCircuitNumber = useRecoilValue(circuitNumDisplaySelector)
|
||||||
const { setModuleStatisticsData } = useCircuitTrestle()
|
const { setModuleStatisticsData } = useCircuitTrestle()
|
||||||
@ -60,10 +59,6 @@ export default function PassivityCircuitAllocation(props) {
|
|||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
targetModulesRef.current = targetModules
|
|
||||||
}, [targetModules])
|
|
||||||
|
|
||||||
const handleTargetModules = (obj) => {
|
const handleTargetModules = (obj) => {
|
||||||
if (!Array.isArray(targetModules)) {
|
if (!Array.isArray(targetModules)) {
|
||||||
setTargetModules([])
|
setTargetModules([])
|
||||||
@ -84,7 +79,6 @@ export default function PassivityCircuitAllocation(props) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleCircuitNumberFix = () => {
|
const handleCircuitNumberFix = () => {
|
||||||
const pcsTpCd = selectedPcs.pcsTpCd // 실내집중형, 옥외멀티형
|
|
||||||
let uniqueCircuitNumbers = [
|
let uniqueCircuitNumbers = [
|
||||||
...new Set(
|
...new Set(
|
||||||
canvas
|
canvas
|
||||||
@ -97,13 +91,13 @@ export default function PassivityCircuitAllocation(props) {
|
|||||||
const surfaceList = targetModules.map((module) => {
|
const surfaceList = targetModules.map((module) => {
|
||||||
return canvas.getObjects().filter((obj) => obj.id === canvas.getObjects().filter((obj) => obj.id === module)[0].surfaceId)[0]
|
return canvas.getObjects().filter((obj) => obj.id === canvas.getObjects().filter((obj) => obj.id === module)[0].surfaceId)[0]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (surfaceList.length > 1) {
|
||||||
let surfaceType = {}
|
let surfaceType = {}
|
||||||
|
|
||||||
surfaceList.forEach((surface) => {
|
surfaceList.forEach((surface) => {
|
||||||
surfaceType[`${surface.direction}-${surface.roofMaterial.pitch}`] = surface
|
surfaceType[`${surface.direction}-${surface.roofMaterial.pitch}`] = surface
|
||||||
})
|
})
|
||||||
|
|
||||||
if (surfaceList.length > 1) {
|
|
||||||
if (Object.keys(surfaceType).length > 1) {
|
if (Object.keys(surfaceType).length > 1) {
|
||||||
swalFire({
|
swalFire({
|
||||||
text: getMessage('module.circuit.fix.not.same.roof.error'),
|
text: getMessage('module.circuit.fix.not.same.roof.error'),
|
||||||
@ -113,7 +107,6 @@ export default function PassivityCircuitAllocation(props) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!circuitNumber || circuitNumber === 0) {
|
if (!circuitNumber || circuitNumber === 0) {
|
||||||
swalFire({
|
swalFire({
|
||||||
text: getMessage('module.circuit.minimun.error'),
|
text: getMessage('module.circuit.minimun.error'),
|
||||||
@ -121,46 +114,14 @@ export default function PassivityCircuitAllocation(props) {
|
|||||||
icon: 'warning',
|
icon: 'warning',
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
} else if (targetModules.length === 0) {
|
||||||
|
|
||||||
if (targetModules.length === 0) {
|
|
||||||
swalFire({
|
swalFire({
|
||||||
text: getMessage('module.not.found'),
|
text: getMessage('module.not.found'),
|
||||||
type: 'alert',
|
type: 'alert',
|
||||||
icon: 'warning',
|
icon: 'warning',
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
} else if (selectedModels.length > 1) {
|
||||||
|
|
||||||
switch (pcsTpCd) {
|
|
||||||
case 'INDFCS': {
|
|
||||||
const originHaveThisPcsModules = canvas
|
|
||||||
.getObjects()
|
|
||||||
.filter((obj) => obj.name === POLYGON_TYPE.MODULE && obj.pcs && obj.pcs.id === selectedPcs.id)
|
|
||||||
// 이미 해당 pcs로 설치된 모듈의 surface의 방향을 구한다.
|
|
||||||
const originSurfaceList = canvas
|
|
||||||
.getObjects()
|
|
||||||
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && originHaveThisPcsModules.map((obj) => obj.surfaceId).includes(obj.id))
|
|
||||||
|
|
||||||
originSurfaceList.concat(originSurfaceList).forEach((surface) => {
|
|
||||||
surfaceType[`${surface.direction}-${surface.roofMaterial.pitch}`] = surface
|
|
||||||
})
|
|
||||||
|
|
||||||
if (surfaceList.length > 1) {
|
|
||||||
if (Object.keys(surfaceType).length > 1) {
|
|
||||||
swalFire({
|
|
||||||
text: getMessage('module.circuit.fix.not.same.roof.error'),
|
|
||||||
type: 'alert',
|
|
||||||
icon: 'warning',
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case 'OUTDMULTI': {
|
|
||||||
if (selectedModels.length > 1) {
|
|
||||||
let result = false
|
let result = false
|
||||||
|
|
||||||
uniqueCircuitNumbers.forEach((number) => {
|
uniqueCircuitNumbers.forEach((number) => {
|
||||||
@ -180,8 +141,6 @@ export default function PassivityCircuitAllocation(props) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let tempSelectedPcs = { ...selectedPcs }
|
let tempSelectedPcs = { ...selectedPcs }
|
||||||
canvas.discardActiveObject()
|
canvas.discardActiveObject()
|
||||||
@ -230,7 +189,6 @@ export default function PassivityCircuitAllocation(props) {
|
|||||||
roofSurfaceId: surface.id,
|
roofSurfaceId: surface.id,
|
||||||
roofSurface: surface.direction,
|
roofSurface: surface.direction,
|
||||||
roofSurfaceIncl: +canvas.getObjects().filter((obj) => obj.id === surface.parentId)[0].pitch,
|
roofSurfaceIncl: +canvas.getObjects().filter((obj) => obj.id === surface.parentId)[0].pitch,
|
||||||
roofSurfaceNorthYn: surface.direction === 'north' ? 'Y' : 'N',
|
|
||||||
moduleList: surface.modules.map((module) => {
|
moduleList: surface.modules.map((module) => {
|
||||||
return {
|
return {
|
||||||
itemId: module.moduleInfo.itemId,
|
itemId: module.moduleInfo.itemId,
|
||||||
@ -312,12 +270,6 @@ export default function PassivityCircuitAllocation(props) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
targetModules.forEach((module) => {
|
|
||||||
const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE)
|
|
||||||
const targetModule = modules.find((obj) => obj.id === module)
|
|
||||||
targetModule.pcs = selectedPcs
|
|
||||||
})
|
|
||||||
|
|
||||||
setTargetModules([])
|
setTargetModules([])
|
||||||
setCircuitNumber(+circuitNumber + 1)
|
setCircuitNumber(+circuitNumber + 1)
|
||||||
setModuleStatisticsData()
|
setModuleStatisticsData()
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
import React, { useEffect } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { POLYGON_TYPE } from '@/common/common'
|
import { POLYGON_TYPE } from '@/common/common'
|
||||||
import { useEvent } from '@/hooks/useEvent'
|
import { useEvent } from '@/hooks/useEvent'
|
||||||
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
||||||
import { outlineDisplaySelector } from '@/store/settingAtom'
|
|
||||||
import { useRecoilValue } from 'recoil'
|
|
||||||
|
|
||||||
export default function FirstOption(props) {
|
export default function FirstOption(props) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -13,7 +11,6 @@ export default function FirstOption(props) {
|
|||||||
const { option1, option2, dimensionDisplay } = settingModalFirstOptions
|
const { option1, option2, dimensionDisplay } = settingModalFirstOptions
|
||||||
const { initEvent } = useEvent()
|
const { initEvent } = useEvent()
|
||||||
const { setSurfaceShapePattern } = useRoofFn()
|
const { setSurfaceShapePattern } = useRoofFn()
|
||||||
const outlineDisplay = useRecoilValue(outlineDisplaySelector)
|
|
||||||
|
|
||||||
// 데이터를 최초 한 번만 조회
|
// 데이터를 최초 한 번만 조회
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -21,13 +18,6 @@ export default function FirstOption(props) {
|
|||||||
setSettingsDataSave({ ...settingsData })
|
setSettingsDataSave({ ...settingsData })
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const outline = canvas.getObjects().filter((obj) => obj.name === 'originRoofOuterLine')
|
|
||||||
outline.forEach((obj) => {
|
|
||||||
obj.visible = outlineDisplay
|
|
||||||
})
|
|
||||||
}, [outlineDisplay])
|
|
||||||
|
|
||||||
const onClickOption = async (item) => {
|
const onClickOption = async (item) => {
|
||||||
let dimensionDisplay = settingModalFirstOptions?.dimensionDisplay
|
let dimensionDisplay = settingModalFirstOptions?.dimensionDisplay
|
||||||
let option1 = settingModalFirstOptions?.option1
|
let option1 = settingModalFirstOptions?.option1
|
||||||
@ -68,12 +58,7 @@ export default function FirstOption(props) {
|
|||||||
// setSettingModalFirstOptions({ ...settingModalFirstOptions, option1: [...options] })
|
// setSettingModalFirstOptions({ ...settingModalFirstOptions, option1: [...options] })
|
||||||
}
|
}
|
||||||
|
|
||||||
setSettingsData({
|
setSettingsData({ ...settingsData, option1: [...option1], option2: [...option2], dimensionDisplay: [...dimensionDisplay] })
|
||||||
...settingsData,
|
|
||||||
option1: [...option1],
|
|
||||||
option2: [...option2],
|
|
||||||
dimensionDisplay: [...dimensionDisplay],
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// useEffect(() => {
|
// useEffect(() => {
|
||||||
|
|||||||
@ -31,11 +31,8 @@ export function useCommonUtils() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
commonTextMode()
|
commonTextMode()
|
||||||
if (commonUtils.dimension) {
|
if (commonUtils.dimension) {
|
||||||
generateTempGrid()
|
|
||||||
commonDimensionMode()
|
commonDimensionMode()
|
||||||
return
|
return
|
||||||
} else {
|
|
||||||
removeTempGrid()
|
|
||||||
}
|
}
|
||||||
if (commonUtils.distance) {
|
if (commonUtils.distance) {
|
||||||
commonDistanceMode()
|
commonDistanceMode()
|
||||||
@ -648,7 +645,6 @@ export function useCommonUtils() {
|
|||||||
lockMovementY: true,
|
lockMovementY: true,
|
||||||
name: obj.name,
|
name: obj.name,
|
||||||
editable: false,
|
editable: false,
|
||||||
selectable: true, // 복사된 객체 선택 가능하도록 설정
|
|
||||||
id: uuidv4(), //복사된 객체라 새로 따준다
|
id: uuidv4(), //복사된 객체라 새로 따준다
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -657,25 +653,19 @@ export function useCommonUtils() {
|
|||||||
|
|
||||||
//배치면일 경우
|
//배치면일 경우
|
||||||
if (obj.name === 'roof') {
|
if (obj.name === 'roof') {
|
||||||
clonedObj.canvas = canvas // canvas 참조 설정
|
clonedObj.setCoords()
|
||||||
|
clonedObj.fire('modified')
|
||||||
|
clonedObj.fire('polygonMoved')
|
||||||
clonedObj.set({
|
clonedObj.set({
|
||||||
direction: obj.direction,
|
direction: obj.direction,
|
||||||
directionText: obj.directionText,
|
directionText: obj.directionText,
|
||||||
roofMaterial: obj.roofMaterial,
|
roofMaterial: obj.roofMaterial,
|
||||||
stroke: 'black', // 복사된 객체는 선택 해제 상태의 색상으로 설정
|
|
||||||
selectable: true, // 선택 가능하도록 설정
|
|
||||||
evented: true, // 마우스 이벤트를 받을 수 있도록 설정
|
|
||||||
isFixed: false, // containsPoint에서 특별 처리 방지
|
|
||||||
})
|
})
|
||||||
|
|
||||||
obj.lines.forEach((line, index) => {
|
obj.lines.forEach((line, index) => {
|
||||||
clonedObj.lines[index].set({ attributes: line.attributes })
|
clonedObj.lines[index].set({ attributes: line.attributes })
|
||||||
})
|
})
|
||||||
|
|
||||||
clonedObj.fire('polygonMoved') // 내부 좌표 재계산 (points, pathOffset)
|
|
||||||
clonedObj.fire('modified')
|
|
||||||
clonedObj.setCoords() // 모든 속성 설정 후 좌표 업데이트
|
|
||||||
canvas.setActiveObject(clonedObj)
|
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
addLengthText(clonedObj) //수치 추가
|
addLengthText(clonedObj) //수치 추가
|
||||||
drawDirectionArrow(clonedObj) //방향 화살표 추가
|
drawDirectionArrow(clonedObj) //방향 화살표 추가
|
||||||
@ -915,45 +905,6 @@ export function useCommonUtils() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const generateTempGrid = () => {
|
|
||||||
if (!canvas) return
|
|
||||||
|
|
||||||
const objects = canvas.getObjects().filter((obj) => ['QPolygon'].includes(obj.type))
|
|
||||||
const gridLines = []
|
|
||||||
|
|
||||||
objects.forEach((obj) => {
|
|
||||||
const lines = obj.lines
|
|
||||||
|
|
||||||
lines.forEach((line) => {
|
|
||||||
const gridLine = new fabric.Line([line.x1, line.y1, line.x2, line.y2], {
|
|
||||||
stroke: 'gray',
|
|
||||||
strokeWidth: 1,
|
|
||||||
selectable: false,
|
|
||||||
evented: false,
|
|
||||||
opacity: 0.5,
|
|
||||||
name: 'tempGrid',
|
|
||||||
direction: line.x1 === line.x2 ? 'vertical' : 'horizontal',
|
|
||||||
visible: false,
|
|
||||||
})
|
|
||||||
gridLines.push(gridLine)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
gridLines.forEach((line) => {
|
|
||||||
canvas.add(line)
|
|
||||||
})
|
|
||||||
|
|
||||||
canvas.renderAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
const removeTempGrid = () => {
|
|
||||||
if (!canvas) return
|
|
||||||
|
|
||||||
const tempGrids = canvas.getObjects().filter((obj) => obj.name === 'tempGrid' && !obj.visible)
|
|
||||||
tempGrids.forEach((grid) => canvas.remove(grid))
|
|
||||||
canvas.renderAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
commonFunctions,
|
commonFunctions,
|
||||||
dimensionSettings,
|
dimensionSettings,
|
||||||
@ -965,7 +916,5 @@ export function useCommonUtils() {
|
|||||||
editText,
|
editText,
|
||||||
changeDimensionExtendLine,
|
changeDimensionExtendLine,
|
||||||
deleteOuterLineObject,
|
deleteOuterLineObject,
|
||||||
generateTempGrid,
|
|
||||||
removeTempGrid,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import {
|
|||||||
basicSettingState,
|
basicSettingState,
|
||||||
correntObjectNoState,
|
correntObjectNoState,
|
||||||
corridorDimensionSelector,
|
corridorDimensionSelector,
|
||||||
outlineDisplaySelector,
|
|
||||||
roofDisplaySelector,
|
roofDisplaySelector,
|
||||||
roofMaterialsSelector,
|
roofMaterialsSelector,
|
||||||
selectedRoofMaterialSelector,
|
selectedRoofMaterialSelector,
|
||||||
@ -30,8 +29,6 @@ import { QcastContext } from '@/app/QcastProvider'
|
|||||||
import { usePlan } from '@/hooks/usePlan'
|
import { usePlan } from '@/hooks/usePlan'
|
||||||
import { roofsState } from '@/store/roofAtom'
|
import { roofsState } from '@/store/roofAtom'
|
||||||
import { useText } from '@/hooks/useText'
|
import { useText } from '@/hooks/useText'
|
||||||
import { processEaveHelpLines } from '@/util/skeleton-utils'
|
|
||||||
import { QLine } from '@/components/fabric/QLine'
|
|
||||||
|
|
||||||
export function useRoofAllocationSetting(id) {
|
export function useRoofAllocationSetting(id) {
|
||||||
const canvas = useRecoilValue(canvasState)
|
const canvas = useRecoilValue(canvasState)
|
||||||
@ -62,11 +59,9 @@ export function useRoofAllocationSetting(id) {
|
|||||||
const { saveCanvas } = usePlan()
|
const { saveCanvas } = usePlan()
|
||||||
const [roofsStore, setRoofsStore] = useRecoilState(roofsState)
|
const [roofsStore, setRoofsStore] = useRecoilState(roofsState)
|
||||||
const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState)
|
const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState)
|
||||||
const outerLinePoints = useRecoilValue(outerLinePointsState)
|
|
||||||
const resetPoints = useResetRecoilState(outerLinePointsState)
|
const resetPoints = useResetRecoilState(outerLinePointsState)
|
||||||
const [corridorDimension, setCorridorDimension] = useRecoilState(corridorDimensionSelector)
|
const [corridorDimension, setCorridorDimension] = useRecoilState(corridorDimensionSelector)
|
||||||
const { changeCorridorDimensionText } = useText()
|
const { changeCorridorDimensionText } = useText()
|
||||||
const outlineDisplay = useRecoilValue(outlineDisplaySelector)
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
/** 배치면 초기설정에서 선택한 지붕재 배열 설정 */
|
/** 배치면 초기설정에서 선택한 지붕재 배열 설정 */
|
||||||
@ -308,53 +303,11 @@ export function useRoofAllocationSetting(id) {
|
|||||||
addPopup(popupId, 1, <ActualSizeSetting id={popupId} />)
|
addPopup(popupId, 1, <ActualSizeSetting id={popupId} />)
|
||||||
} else {
|
} else {
|
||||||
apply()
|
apply()
|
||||||
//기존 지붕 선은 남겨둔다.
|
|
||||||
drawOriginRoofLine()
|
|
||||||
resetPoints()
|
resetPoints()
|
||||||
|
|
||||||
basicSettingSave()
|
basicSettingSave()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const drawOriginRoofLine = () => {
|
|
||||||
// outerLinePoints 배열을 이용하여 빨간색 Line 객체들 생성
|
|
||||||
if (outerLinePoints && outerLinePoints.length > 1) {
|
|
||||||
// 연속된 점들을 연결하여 라인 생성
|
|
||||||
for (let i = 0; i < outerLinePoints.length - 1; i++) {
|
|
||||||
const point1 = outerLinePoints[i]
|
|
||||||
const point2 = outerLinePoints[i + 1]
|
|
||||||
|
|
||||||
const line = new fabric.Line([point1.x, point1.y, point2.x, point2.y], {
|
|
||||||
stroke: 'black',
|
|
||||||
strokeDashArray: [5, 2],
|
|
||||||
strokeWidth: 1,
|
|
||||||
selectable: false,
|
|
||||||
name: 'originRoofOuterLine',
|
|
||||||
visible: outlineDisplay,
|
|
||||||
})
|
|
||||||
|
|
||||||
canvas.add(line)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 마지막 점과 첫 점을 연결하여 폐곡선 만들기
|
|
||||||
if (outerLinePoints.length > 2) {
|
|
||||||
const lastPoint = outerLinePoints[outerLinePoints.length - 1]
|
|
||||||
const firstPoint = outerLinePoints[0]
|
|
||||||
|
|
||||||
const closingLine = new fabric.Line([lastPoint.x, lastPoint.y, firstPoint.x, firstPoint.y], {
|
|
||||||
stroke: 'red',
|
|
||||||
strokeWidth: 2,
|
|
||||||
selectable: false,
|
|
||||||
name: 'originRoofOuterLine',
|
|
||||||
})
|
|
||||||
|
|
||||||
canvas.add(closingLine)
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas.renderAll()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 지붕재 오른쪽 마우스 클릭 후 단일로 지붕재 변경 필요한 경우
|
* 지붕재 오른쪽 마우스 클릭 후 단일로 지붕재 변경 필요한 경우
|
||||||
*/
|
*/
|
||||||
@ -451,22 +404,6 @@ export function useRoofAllocationSetting(id) {
|
|||||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
||||||
roofBases.forEach((roofBase) => {
|
roofBases.forEach((roofBase) => {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
const roofEaveHelpLines = canvas.getObjects().filter((obj) => obj.lineName === 'eaveHelpLine' && obj.roofId === roofBase.id)
|
|
||||||
if (roofEaveHelpLines.length > 0) {
|
|
||||||
if (roofBase.lines) {
|
|
||||||
// Filter out any eaveHelpLines that are already in lines to avoid duplicates
|
|
||||||
const existingEaveLineIds = new Set(roofBase.lines.map((line) => line.id))
|
|
||||||
const newEaveLines = roofEaveHelpLines.filter((line) => !existingEaveLineIds.has(line.id))
|
|
||||||
roofBase.lines = [...newEaveLines]
|
|
||||||
} else {
|
|
||||||
roofBase.lines = [...roofEaveHelpLines]
|
|
||||||
}
|
|
||||||
if (!roofBase.innerLines) {
|
|
||||||
roofBase.innerLines = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (roofBase.separatePolygon.length > 0) {
|
if (roofBase.separatePolygon.length > 0) {
|
||||||
splitPolygonWithSeparate(roofBase.separatePolygon)
|
splitPolygonWithSeparate(roofBase.separatePolygon)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -402,8 +402,7 @@ export function useCanvasEvent() {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
zoom = canvasZoom - 10
|
zoom = canvasZoom - 10
|
||||||
if (zoom < 10) {
|
if (zoom < 10) { //50%->10%
|
||||||
//50%->10%
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -413,33 +412,8 @@ export function useCanvasEvent() {
|
|||||||
|
|
||||||
const handleZoomClear = () => {
|
const handleZoomClear = () => {
|
||||||
setCanvasZoom(100)
|
setCanvasZoom(100)
|
||||||
|
canvas.set({ zoom: 1 })
|
||||||
zoomToAllObjects()
|
canvas.viewportTransform = [1, 0, 0, 1, 0, 0]
|
||||||
canvas.renderAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
const zoomToAllObjects = () => {
|
|
||||||
const objects = canvas.getObjects().filter((obj) => obj.visible)
|
|
||||||
if (objects.length === 0) return
|
|
||||||
|
|
||||||
let minX = Infinity,
|
|
||||||
minY = Infinity
|
|
||||||
let maxX = -Infinity,
|
|
||||||
maxY = -Infinity
|
|
||||||
|
|
||||||
objects.forEach((obj) => {
|
|
||||||
const bounds = obj.getBoundingRect()
|
|
||||||
minX = Math.min(minX, bounds.left)
|
|
||||||
minY = Math.min(minY, bounds.top)
|
|
||||||
maxX = Math.max(maxX, bounds.left + bounds.width)
|
|
||||||
maxY = Math.max(maxY, bounds.top + bounds.height)
|
|
||||||
})
|
|
||||||
|
|
||||||
const centerX = (minX + maxX) / 2
|
|
||||||
const centerY = (minY + maxY) / 2
|
|
||||||
const centerPoint = new fabric.Point(centerX, centerY)
|
|
||||||
|
|
||||||
canvas.zoomToPoint(centerPoint, 1)
|
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -42,18 +42,7 @@ export function useCircuitTrestle(executeEffect = false) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// PCS 아이템 목록
|
// PCS 아이템 목록
|
||||||
const getPcsItemList = (isMultiModule = false) => {
|
const getPcsItemList = () => {
|
||||||
if (isMultiModule) {
|
|
||||||
return models
|
|
||||||
.filter((model) => model.pcsTpCd !== 'INDFCS')
|
|
||||||
.map((model) => {
|
|
||||||
return {
|
|
||||||
itemId: model.itemId,
|
|
||||||
pcsMkrCd: model.pcsMkrCd,
|
|
||||||
pcsSerCd: model.pcsSerCd,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return models.map((model) => {
|
return models.map((model) => {
|
||||||
return {
|
return {
|
||||||
itemId: model.itemId,
|
itemId: model.itemId,
|
||||||
@ -64,18 +53,7 @@ export function useCircuitTrestle(executeEffect = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 선택된 PCS 아이템 목록
|
// 선택된 PCS 아이템 목록
|
||||||
const getSelectedPcsItemList = (isMultiModule = false) => {
|
const getSelectedPcsItemList = () => {
|
||||||
if (isMultiModule) {
|
|
||||||
return selectedModels
|
|
||||||
.filter((model) => model.pcsTpCd !== 'INDFCS')
|
|
||||||
.map((model) => {
|
|
||||||
return {
|
|
||||||
itemId: model.itemId,
|
|
||||||
pcsMkrCd: model.pcsMkrCd,
|
|
||||||
pcsSerCd: model.pcsSerCd,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return selectedModels.map((model) => {
|
return selectedModels.map((model) => {
|
||||||
return {
|
return {
|
||||||
itemId: model.itemId,
|
itemId: model.itemId,
|
||||||
@ -117,7 +95,6 @@ export function useCircuitTrestle(executeEffect = false) {
|
|||||||
uniqueId: module.id ? module.id : null,
|
uniqueId: module.id ? module.id : null,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
roofSurfaceNorthYn: obj.direction === 'north' ? 'Y' : 'N',
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter((surface) => surface.moduleList.length > 0)
|
.filter((surface) => surface.moduleList.length > 0)
|
||||||
|
|||||||
@ -845,8 +845,6 @@ export const usePolygon = () => {
|
|||||||
polygonLines.forEach((line) => {
|
polygonLines.forEach((line) => {
|
||||||
line.need = true
|
line.need = true
|
||||||
})
|
})
|
||||||
// 순서에 의존하지 않도록 모든 조합을 먼저 확인한 후 처리
|
|
||||||
const innerLineMapping = new Map() // innerLine -> polygonLine 매핑 저장
|
|
||||||
|
|
||||||
// innerLines와 polygonLines의 겹침을 확인하고 type 변경
|
// innerLines와 polygonLines의 겹침을 확인하고 type 변경
|
||||||
innerLines.forEach((innerLine) => {
|
innerLines.forEach((innerLine) => {
|
||||||
@ -856,28 +854,14 @@ export const usePolygon = () => {
|
|||||||
if (innerLine.attributes && polygonLine.attributes.type) {
|
if (innerLine.attributes && polygonLine.attributes.type) {
|
||||||
// innerLine이 polygonLine보다 긴 경우 polygonLine.need를 false로 변경
|
// innerLine이 polygonLine보다 긴 경우 polygonLine.need를 false로 변경
|
||||||
if (polygonLine.length < innerLine.length) {
|
if (polygonLine.length < innerLine.length) {
|
||||||
if(polygonLine.lineName !== 'eaveHelpLine'){
|
|
||||||
polygonLine.need = false
|
polygonLine.need = false
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// innerLine.attributes.planeSize = innerLine.attributes.planeSize ?? polygonLine.attributes.planeSize
|
|
||||||
// innerLine.attributes.actualSize = innerLine.attributes.actualSize ?? polygonLine.attributes.actualSize
|
|
||||||
// innerLine.attributes.type = polygonLine.attributes.type
|
|
||||||
// innerLine.direction = polygonLine.direction
|
|
||||||
// innerLine.attributes.isStart = true
|
|
||||||
// innerLine.parentLine = polygonLine
|
|
||||||
|
|
||||||
|
|
||||||
// 매핑된 innerLine의 attributes를 변경 (교차점 계산 전에 적용)
|
|
||||||
innerLineMapping.forEach((polygonLine, innerLine) => {
|
|
||||||
innerLine.attributes.planeSize = innerLine.attributes.planeSize ?? polygonLine.attributes.planeSize
|
innerLine.attributes.planeSize = innerLine.attributes.planeSize ?? polygonLine.attributes.planeSize
|
||||||
innerLine.attributes.actualSize = innerLine.attributes.actualSize ?? polygonLine.attributes.actualSize
|
innerLine.attributes.actualSize = innerLine.attributes.actualSize ?? polygonLine.attributes.actualSize
|
||||||
innerLine.attributes.type = polygonLine.attributes.type
|
innerLine.attributes.type = polygonLine.attributes.type
|
||||||
innerLine.direction = polygonLine.direction
|
innerLine.direction = polygonLine.direction
|
||||||
innerLine.attributes.isStart = true
|
innerLine.attributes.isStart = true
|
||||||
innerLine.parentLine = polygonLine
|
innerLine.parentLine = polygonLine
|
||||||
})
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -1387,7 +1371,7 @@ export const usePolygon = () => {
|
|||||||
let representLine
|
let representLine
|
||||||
|
|
||||||
// 지붕을 그리면서 기존 polygon의 line중 연결된 line을 찾는다.
|
// 지붕을 그리면서 기존 polygon의 line중 연결된 line을 찾는다.
|
||||||
[...polygonLines, ...innerLines].forEach((line) => {
|
;[...polygonLines, ...innerLines].forEach((line) => {
|
||||||
let startFlag = false
|
let startFlag = false
|
||||||
let endFlag = false
|
let endFlag = false
|
||||||
const startPoint = line.startPoint
|
const startPoint = line.startPoint
|
||||||
@ -1583,126 +1567,52 @@ export const usePolygon = () => {
|
|||||||
|
|
||||||
// ==== Dijkstra pathfinding ====
|
// ==== Dijkstra pathfinding ====
|
||||||
|
|
||||||
// function findShortestPath(start, end, graph, epsilon = 1) {
|
|
||||||
// const startKey = pointToKey(start, epsilon)
|
|
||||||
// const endKey = pointToKey(end, epsilon)
|
|
||||||
//
|
|
||||||
// const distances = {}
|
|
||||||
// const previous = {}
|
|
||||||
// const visited = new Set()
|
|
||||||
// const queue = [{ key: startKey, dist: 0 }]
|
|
||||||
//
|
|
||||||
// for (const key in graph) distances[key] = Infinity
|
|
||||||
// distances[startKey] = 0
|
|
||||||
//
|
|
||||||
// while (queue.length > 0) {
|
|
||||||
// queue.sort((a, b) => a.dist - b.dist)
|
|
||||||
// const { key } = queue.shift()
|
|
||||||
// if (visited.has(key)) continue
|
|
||||||
// visited.add(key)
|
|
||||||
//
|
|
||||||
// for (const neighbor of graph[key] || []) {
|
|
||||||
// const neighborKey = pointToKey(neighbor.point, epsilon)
|
|
||||||
// const alt = distances[key] + neighbor.distance
|
|
||||||
// if (alt < distances[neighborKey]) {
|
|
||||||
// distances[neighborKey] = alt
|
|
||||||
// previous[neighborKey] = key
|
|
||||||
// queue.push({ key: neighborKey, dist: alt })
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// const path = []
|
|
||||||
// let currentKey = endKey
|
|
||||||
//
|
|
||||||
// if (!previous[currentKey]) return null
|
|
||||||
//
|
|
||||||
// while (currentKey !== startKey) {
|
|
||||||
// const [x, y] = currentKey.split(',').map(Number)
|
|
||||||
// path.unshift({ x, y })
|
|
||||||
// currentKey = previous[currentKey]
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// const [sx, sy] = startKey.split(',').map(Number)
|
|
||||||
// path.unshift({ x: sx, y: sy })
|
|
||||||
//
|
|
||||||
// return path
|
|
||||||
// }
|
|
||||||
|
|
||||||
function findShortestPath(start, end, graph, epsilon = 1) {
|
function findShortestPath(start, end, graph, epsilon = 1) {
|
||||||
const startKey = pointToKey(start, epsilon);
|
const startKey = pointToKey(start, epsilon)
|
||||||
const endKey = pointToKey(end, epsilon);
|
const endKey = pointToKey(end, epsilon)
|
||||||
|
|
||||||
// 거리와 이전 노드 추적
|
const distances = {}
|
||||||
const distances = { [startKey]: 0 };
|
const previous = {}
|
||||||
const previous = {};
|
const visited = new Set()
|
||||||
const visited = new Set();
|
const queue = [{ key: startKey, dist: 0 }]
|
||||||
|
|
||||||
// 우선순위 큐 (거리가 짧은 순으로 정렬)
|
for (const key in graph) distances[key] = Infinity
|
||||||
const queue = [{ key: startKey, dist: 0 }];
|
distances[startKey] = 0
|
||||||
|
|
||||||
// 모든 노드 초기화
|
while (queue.length > 0) {
|
||||||
for (const key in graph) {
|
queue.sort((a, b) => a.dist - b.dist)
|
||||||
if (key !== startKey) {
|
const { key } = queue.shift()
|
||||||
distances[key] = Infinity;
|
if (visited.has(key)) continue
|
||||||
}
|
visited.add(key)
|
||||||
}
|
|
||||||
|
|
||||||
// 우선순위 큐에서 다음 노드 선택
|
for (const neighbor of graph[key] || []) {
|
||||||
const getNextNode = () => {
|
const neighborKey = pointToKey(neighbor.point, epsilon)
|
||||||
if (queue.length === 0) return null;
|
const alt = distances[key] + neighbor.distance
|
||||||
queue.sort((a, b) => a.dist - b.dist);
|
if (alt < distances[neighborKey]) {
|
||||||
return queue.shift();
|
distances[neighborKey] = alt
|
||||||
};
|
previous[neighborKey] = key
|
||||||
|
queue.push({ key: neighborKey, dist: alt })
|
||||||
let current;
|
|
||||||
while ((current = getNextNode())) {
|
|
||||||
const currentKey = current.key;
|
|
||||||
|
|
||||||
// 목적지에 도달하면 종료
|
|
||||||
if (currentKey === endKey) break;
|
|
||||||
|
|
||||||
// 이미 방문한 노드는 건너뜀
|
|
||||||
if (visited.has(currentKey)) continue;
|
|
||||||
visited.add(currentKey);
|
|
||||||
|
|
||||||
// 인접 노드 탐색
|
|
||||||
for (const neighbor of graph[currentKey] || []) {
|
|
||||||
const neighborKey = pointToKey(neighbor.point, epsilon);
|
|
||||||
if (visited.has(neighborKey)) continue;
|
|
||||||
|
|
||||||
const alt = distances[currentKey] + neighbor.distance;
|
|
||||||
|
|
||||||
// 더 짧은 경로를 찾은 경우 업데이트
|
|
||||||
if (alt < (distances[neighborKey] || Infinity)) {
|
|
||||||
distances[neighborKey] = alt;
|
|
||||||
previous[neighborKey] = currentKey;
|
|
||||||
|
|
||||||
// 우선순위 큐에 추가
|
|
||||||
queue.push({ key: neighborKey, dist: alt });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 경로 재구성
|
const path = []
|
||||||
const path = [];
|
let currentKey = endKey
|
||||||
let currentKey = endKey;
|
|
||||||
|
|
||||||
// 시작점에 도달할 때까지 역추적
|
if (!previous[currentKey]) return null
|
||||||
while (previous[currentKey] !== undefined) {
|
|
||||||
const [x, y] = currentKey.split(',').map(Number);
|
while (currentKey !== startKey) {
|
||||||
path.unshift({ x, y });
|
const [x, y] = currentKey.split(',').map(Number)
|
||||||
currentKey = previous[currentKey];
|
path.unshift({ x, y })
|
||||||
|
currentKey = previous[currentKey]
|
||||||
}
|
}
|
||||||
|
|
||||||
// 시작점 추가
|
const [sx, sy] = startKey.split(',').map(Number)
|
||||||
if (path.length > 0) {
|
path.unshift({ x: sx, y: sy })
|
||||||
const [sx, sy] = startKey.split(',').map(Number);
|
|
||||||
path.unshift({ x: sx, y: sy });
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
return path.length > 0 ? path : null;
|
|
||||||
}
|
|
||||||
// 최종 함수
|
// 최종 함수
|
||||||
function getPath(start, end, graph, epsilon = 1) {
|
function getPath(start, end, graph, epsilon = 1) {
|
||||||
// startPoint와 arrivalPoint가 될 수 있는 점은 line.attributes.type이 'default' 혹은 null이 아닌 line인 경우에만 가능
|
// startPoint와 arrivalPoint가 될 수 있는 점은 line.attributes.type이 'default' 혹은 null이 아닌 line인 경우에만 가능
|
||||||
|
|||||||
@ -1089,7 +1089,6 @@
|
|||||||
"module.circuit.minimun.error": "回路番号は1以上の数値を入力してください。",
|
"module.circuit.minimun.error": "回路番号は1以上の数値を入力してください。",
|
||||||
"module.already.exist.error": "回路番号が同じで異なるパワーコンディショナのモジュールがあります。 別の回路番号を設定してください。",
|
"module.already.exist.error": "回路番号が同じで異なるパワーコンディショナのモジュールがあります。 別の回路番号を設定してください。",
|
||||||
"module.circuit.fix.not.same.roof.error": "異なる屋根面のモジュールが選択されています。 モジュールの選択をや直してください。",
|
"module.circuit.fix.not.same.roof.error": "異なる屋根面のモジュールが選択されています。 モジュールの選択をや直してください。",
|
||||||
"module.circuit.indoor.focused.error": "混合モジュールと屋内集中PCSを組み合わせる場合は、手動回路割り当てのみ対応可能です。",
|
|
||||||
"construction.length.difference": "屋根面工法をすべて選択してください。",
|
"construction.length.difference": "屋根面工法をすべて選択してください。",
|
||||||
"menu.validation.canvas.roof": "パネルを配置するには、屋根面を入力する必要があります。",
|
"menu.validation.canvas.roof": "パネルを配置するには、屋根面を入力する必要があります。",
|
||||||
"batch.object.outside.roof": "オブジェクトは屋根に設置する必要があります。",
|
"batch.object.outside.roof": "オブジェクトは屋根に設置する必要があります。",
|
||||||
|
|||||||
@ -1089,7 +1089,6 @@
|
|||||||
"module.circuit.minimun.error": "회로번호는 1 이상입력해주세요.",
|
"module.circuit.minimun.error": "회로번호는 1 이상입력해주세요.",
|
||||||
"module.already.exist.error": "회로번호가 같은 다른 파워 컨디셔너 모듈이 있습니다. 다른 회로번호를 설정하십시오.",
|
"module.already.exist.error": "회로번호가 같은 다른 파워 컨디셔너 모듈이 있습니다. 다른 회로번호를 설정하십시오.",
|
||||||
"module.circuit.fix.not.same.roof.error": "다른 지붕면의 모듈이 선택되어 있습니다. 모듈 선택을 다시 하세요.",
|
"module.circuit.fix.not.same.roof.error": "다른 지붕면의 모듈이 선택되어 있습니다. 모듈 선택을 다시 하세요.",
|
||||||
"module.circuit.indoor.focused.error": "혼합 모듈과 실내 집중형 PCS를 조합하는 경우, 수동 회로 할당만 가능합니다.",
|
|
||||||
"construction.length.difference": "지붕면 공법을 모두 선택하십시오.",
|
"construction.length.difference": "지붕면 공법을 모두 선택하십시오.",
|
||||||
"menu.validation.canvas.roof": "패널을 배치하려면 지붕면을 입력해야 합니다.",
|
"menu.validation.canvas.roof": "패널을 배치하려면 지붕면을 입력해야 합니다.",
|
||||||
"batch.object.outside.roof": "오브젝트는 지붕내에 설치해야 합니다.",
|
"batch.object.outside.roof": "오브젝트는 지붕내에 설치해야 합니다.",
|
||||||
|
|||||||
@ -460,11 +460,7 @@ button{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-select{
|
|
||||||
height: 20px;
|
|
||||||
color: #fff !important;
|
|
||||||
font-size: 11px !important;
|
|
||||||
}
|
|
||||||
// input
|
// input
|
||||||
.form-input{
|
.form-input{
|
||||||
label{
|
label{
|
||||||
|
|||||||
@ -269,7 +269,7 @@ export const getDegreeByChon = (chon) => {
|
|||||||
* @returns {number}
|
* @returns {number}
|
||||||
*/
|
*/
|
||||||
export const getChonByDegree = (degree) => {
|
export const getChonByDegree = (degree) => {
|
||||||
return Number((Math.tan((degree * Math.PI) / 180) * 10).toFixed(2))
|
return Number((Math.tan((degree * Math.PI) / 180) * 10).toFixed(1))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1036,11 +1036,11 @@ export const getDegreeInOrientation = (degree) => {
|
|||||||
{ min: -51, max: -37, value: -45 },
|
{ min: -51, max: -37, value: -45 },
|
||||||
{ min: -36, max: -22, value: -30 },
|
{ min: -36, max: -22, value: -30 },
|
||||||
{ min: -21, max: -7, value: -15 },
|
{ min: -21, max: -7, value: -15 },
|
||||||
{ min: -6, max: 0, value: 0 },
|
{ min: -6, max: 0, value: 0 }
|
||||||
]
|
]
|
||||||
|
|
||||||
// 해당 범위에 맞는 값 찾기
|
// 해당 범위에 맞는 값 찾기
|
||||||
const range = degreeRanges.find((range) => degree >= range.min && degree <= range.max)
|
const range = degreeRanges.find(range => degree >= range.min && degree <= range.max)
|
||||||
return range ? range.value : degree
|
return range ? range.value : degree
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user