육지붕 모듈 작업
This commit is contained in:
parent
7b3541f73f
commit
aa2425bf81
@ -47,17 +47,17 @@ export default function PitchModule({}) {
|
||||
setSelectedModules(option) //선택값 저장
|
||||
setModuleSelectionData({
|
||||
...moduleSelectionData,
|
||||
flatModule: option,
|
||||
module: option,
|
||||
})
|
||||
moduleSelectedDataTrigger({
|
||||
...moduleSelectionData,
|
||||
flatModule: option,
|
||||
module: option,
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (isObjectNotEmpty(moduleSelectionData.flatModule) && moduleList.length > 0) {
|
||||
handleChangeModule(moduleSelectionData.flatModule)
|
||||
if (isObjectNotEmpty(moduleSelectionData.module) && moduleList.length > 0) {
|
||||
handleChangeModule(moduleSelectionData.module)
|
||||
}
|
||||
}, [moduleList])
|
||||
|
||||
|
||||
@ -69,7 +69,7 @@ const PitchPlacement = forwardRef((props, refs) => {
|
||||
excretaLine.forEach((line) => {
|
||||
line.set({
|
||||
stroke: '#642EFB',
|
||||
strokeWidth: 5,
|
||||
strokeWidth: 3,
|
||||
surfaceId: surface.surfaceId,
|
||||
name: 'flatExcretaLine',
|
||||
})
|
||||
@ -89,10 +89,10 @@ const PitchPlacement = forwardRef((props, refs) => {
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!moduleSelectionData.flatModule) return // null 오류 차단 로직 추가
|
||||
if (moduleSelectionData && moduleSelectionData.flatModule.itemList.length > 0) {
|
||||
if (!moduleSelectionData.module) return // null 오류 차단 로직 추가
|
||||
if (moduleSelectionData && moduleSelectionData.module.itemList.length > 0) {
|
||||
let initCheckedModule = {}
|
||||
moduleSelectionData.flatModule.itemList.forEach((obj, index) => {
|
||||
moduleSelectionData.module.itemList.forEach((obj, index) => {
|
||||
if (index === 0) {
|
||||
initCheckedModule = { [obj.itemId]: true }
|
||||
} else {
|
||||
|
||||
@ -3,7 +3,7 @@ import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
|
||||
import { canvasSettingState, canvasState, checkedModuleState, currentObjectState, isManualModuleSetupState } from '@/store/canvasAtom'
|
||||
import { rectToPolygon, polygonToTurfPolygon, calculateVisibleModuleHeight, getDegreeByChon } from '@/util/canvas-util'
|
||||
import { addedRoofsState, basicSettingState, roofDisplaySelector } from '@/store/settingAtom'
|
||||
import offsetPolygon, { calculateAngle } from '@/util/qpolygon-utils'
|
||||
import offsetPolygon, { calculateAngle, createLinesFromPolygon } from '@/util/qpolygon-utils'
|
||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||
import { moduleSetupSurfaceState, moduleIsSetupState } from '@/store/canvasAtom'
|
||||
import { useEvent } from '@/hooks/useEvent'
|
||||
@ -239,7 +239,6 @@ export function useModuleBasicSetting(tabNum) {
|
||||
toggleSelection(isExistSurface)
|
||||
})
|
||||
} else {
|
||||
let offsetLength = canvasSetting.roofSizeSet === '3' ? -30 : (trestleDetail.eaveIntvl / 10) * -1
|
||||
setSurfaceShapePattern(roof, roofDisplay.column, true, roof.roofMaterial) //패턴 변경
|
||||
// let offsetPoints = createPaddingPolygon(createRoofPolygon(roof.points), roof.lines).vertices //안쪽 offset
|
||||
let offsetPoints = null
|
||||
@ -252,10 +251,16 @@ export function useModuleBasicSetting(tabNum) {
|
||||
//margin polygon 의 point가 기준 polygon의 밖에 있는지 판단한다.
|
||||
const allPointsOutside = result.every((point) => !originPolygon.inPolygon(point))
|
||||
|
||||
if (allPointsOutside) {
|
||||
offsetPoints = createMarginPolygon(polygon, roof.lines).vertices
|
||||
if (canvasSetting.roofSizeSet == '3') {
|
||||
//육지붕일때는 그냥 하드코딩
|
||||
offsetPoints = offsetPolygon(roof.points, -30) //육지붕일때
|
||||
} else {
|
||||
offsetPoints = createPaddingPolygon(polygon, roof.lines).vertices
|
||||
//육지붕이 아닐때
|
||||
if (allPointsOutside) {
|
||||
offsetPoints = createMarginPolygon(polygon, roof.lines).vertices
|
||||
} else {
|
||||
offsetPoints = createPaddingPolygon(polygon, roof.lines).vertices
|
||||
}
|
||||
}
|
||||
|
||||
//모듈설치영역?? 생성
|
||||
@ -263,7 +268,7 @@ export function useModuleBasicSetting(tabNum) {
|
||||
const surfaceId = uuidv4()
|
||||
let isNorth = false
|
||||
|
||||
if (canvasSetting.roofSizeSet !== '3') {
|
||||
if (canvasSetting.roofSizeSet != '3') {
|
||||
//북면이 있지만
|
||||
if (roof.directionText && roof.directionText.indexOf('北') > -1) {
|
||||
//북쪽일때 해당 서북서, 동북동은 제외한다고 한다
|
||||
@ -2895,8 +2900,13 @@ export function useModuleBasicSetting(tabNum) {
|
||||
targetRoof.angle = -angle
|
||||
targetSurface.angle = -angle
|
||||
|
||||
const newLines = createLinesFromPolygon(targetSurface.getCurrentPoints())
|
||||
targetSurface.set({ lines: newLines })
|
||||
|
||||
targetRoof.fire('modified')
|
||||
targetSurface.fire('modified')
|
||||
targetRoof.setCoords()
|
||||
targetSurface.setCoords()
|
||||
moduleSetupSurfaces.push(targetSurface)
|
||||
}
|
||||
canvas.remove(obj)
|
||||
@ -2990,37 +3000,92 @@ export function useModuleBasicSetting(tabNum) {
|
||||
|
||||
let moduleGroup = []
|
||||
|
||||
const flatRoofDownFlowSetupModule = (surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) => {
|
||||
checkedModule.forEach((module, index) => {
|
||||
const { width, height } = getModuleWidthHeight(maxLengthLine, moduleSetupSurface, module)
|
||||
const flatRoofDownFlowSetupModule = (
|
||||
surfaceMaxLines,
|
||||
maxLengthLine,
|
||||
moduleSetupArray,
|
||||
moduleSetupSurface,
|
||||
intvHor,
|
||||
intvVer,
|
||||
containsBatchObjects,
|
||||
) => {
|
||||
let setupModule = []
|
||||
|
||||
const flowLines = getFlowLines(moduleSetupSurface, height)
|
||||
let installedLastHeightCoord = 0 //마지막으로 설치된 모듈의 좌표
|
||||
let installedModuleHeightCount = 0 //마지막으로 설치된 모듈의 카운트
|
||||
let flowLines
|
||||
|
||||
let startPoint = flowLines.bottom
|
||||
checkedModule.forEach((module, moduleIndex) => {
|
||||
//모듈의 넓이 높이를 가져옴 (복시도 촌수 적용)
|
||||
//1번 깔았던 모듈 기준으로 잡야아함
|
||||
let { width, height } = getModuleWidthHeight(maxLengthLine, moduleSetupSurface, module)
|
||||
|
||||
const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측
|
||||
const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측
|
||||
const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단
|
||||
if (moduleIndex === 0) {
|
||||
flowLines = getFlowLines(moduleSetupSurface, height)
|
||||
if (flowLines.bottom.type === 'curve') {
|
||||
flowLines = getFlowLines(moduleSetupSurface, width)
|
||||
}
|
||||
}
|
||||
|
||||
let totalLeftEndPoint = maxLeftEndPoint - startPoint.x1
|
||||
let totalTopEndPoint = maxTopEndPoint - startPoint.y1
|
||||
let totalWidth = Math.ceil(Math.abs(maxRightEndPoint - maxLeftEndPoint) / width)
|
||||
let diffLeftEndPoint = Math.abs(totalLeftEndPoint / width)
|
||||
let diffTopEndPoint = Math.abs(totalTopEndPoint / height)
|
||||
let startColPoint = Math.abs(width * Math.ceil(diffLeftEndPoint) - startPoint.x1)
|
||||
let tempMaxWidth = width //최대배치인지 확인하려고 넣음
|
||||
//육지붕이 아닐때만 넣는다 육지붕일땐 클릭 이벤트에 별도로 넣어놓음
|
||||
const moduleArray = []
|
||||
|
||||
for (let j = 0; j < diffTopEndPoint; j++) {
|
||||
bottomMargin = marginHeight * j
|
||||
for (let i = 0; i <= totalWidth; i++) {
|
||||
leftMargin = marginWidth * i
|
||||
let calcAreaWidth = flowLines.right.x1 - flowLines.left.x1 //오른쪽 x에서 왼쪽 x를 뺀 가운데를 찾는 로직
|
||||
let calcModuleWidthCount = calcAreaWidth / (width + intvHor) //뺀 공간에서 모듈을 몇개를 넣을수 있는지 확인하는 로직
|
||||
let calcMaxModuleWidthCount = calcModuleWidthCount //최대 모듈 단수가 있기 때문에 최대 단수보다 카운트가 크면 최대 단수로 씀씀
|
||||
let totalModuleWidthCount = Math.floor(calcMaxModuleWidthCount) //치조배치일경우는 한개 더 넣는다
|
||||
|
||||
square = [
|
||||
[startColPoint + tempMaxWidth * i + leftMargin, startPoint.y1 - height * j - bottomMargin],
|
||||
[startColPoint + tempMaxWidth * i + width + leftMargin, startPoint.y1 - height * j - bottomMargin],
|
||||
[startColPoint + tempMaxWidth * i + width + leftMargin, startPoint.y1 - height * j - height - bottomMargin],
|
||||
[startColPoint + tempMaxWidth * i + leftMargin, startPoint.y1 - height * j - height - bottomMargin],
|
||||
[startColPoint + tempMaxWidth * i + leftMargin, startPoint.y1 - height * j - bottomMargin],
|
||||
let calcAreaheight = flowLines.bottom.y1 - flowLines.top.y1 //오른쪽 y에서 왼쪽 y를 뺀 가운데를 찾는 로직
|
||||
let calcModuleHeightCount = calcAreaheight / (height + intvVer) //뺀 공간에서 모듈을 몇개를 넣을수 있는지 확인하는 로직
|
||||
let calcMaxModuleHeightCount = calcModuleHeightCount //최대 모듈 단수가 있기 때문에 최대 단수보다 카운트가 크면 최대 단수로 씀씀
|
||||
let totalModuleHeightCount = Math.floor(calcMaxModuleHeightCount) //치조배치일경우는 한개 더 넣는다
|
||||
|
||||
let calcStartPoint = flowLines.right.type === 'flat' ? (calcAreaWidth - totalModuleWidthCount * width) / 2 : 0 //반씩 나눠서 중앙에 맞춤 bottom 기준으로 양변이 직선일때만 가운데 정렬
|
||||
let startPointX = flowLines.left.x1 + calcStartPoint //시작점을 만든다
|
||||
|
||||
//근데 양변이 곡선이면 중앙에 맞추기 위해 아래와 위의 길이를 재서 모듈의 길이를 나눠서 들어갈수 있는 갯수가 동일하면 가운데로 정렬 시킨다
|
||||
if (flowLines.left.type === 'curve' && flowLines.right.type === 'curve') {
|
||||
startPointX = flowLines.left.x1 + (calcAreaWidth - totalModuleWidthCount * width) / 2
|
||||
|
||||
if (flowLines.left.x1 < flowLines.bottom.x1) {
|
||||
startPointX = flowLines.left.x1
|
||||
}
|
||||
}
|
||||
|
||||
let heightMargin = 0
|
||||
let widthMargin = 0
|
||||
let chidoriLength = 0
|
||||
let moduleMaxRows = totalModuleHeightCount
|
||||
|
||||
//첫번재 모듈 설치 후 두번째 모듈을 몇개까지 설치 할 수 있는지 계산
|
||||
if (moduleIndex > 0) {
|
||||
moduleMaxRows = moduleMaxRows - installedModuleHeightCount //두번째 모듈일때
|
||||
}
|
||||
|
||||
let isInstall = false
|
||||
|
||||
for (let i = 0; i < moduleMaxRows; i++) {
|
||||
let moduleY = flowLines.bottom.y1 - height * i - 1 //살짝 여유를 준다
|
||||
|
||||
//두번째 모듈 -> 혼합일 경우의 설치될 모듈 높이를 계산
|
||||
if (moduleIndex > 0) {
|
||||
moduleY = installedLastHeightCoord - intvVer
|
||||
}
|
||||
|
||||
//첫번째는 붙여서 두번째는 마진을 주고 설치
|
||||
heightMargin = i === 0 ? 0 : intvVer * i
|
||||
|
||||
for (let j = 0; j < totalModuleWidthCount; j++) {
|
||||
let moduleX = startPointX + width * j + 1 //5정도 마진을 준다
|
||||
widthMargin = j === 0 ? 0 : intvHor * j // 가로 마진값
|
||||
chidoriLength = 0 //치도리가 아니여도 기본값을 5정도 준다
|
||||
|
||||
let square = [
|
||||
[moduleX + widthMargin, moduleY - height - heightMargin],
|
||||
[moduleX + widthMargin, moduleY - heightMargin],
|
||||
[moduleX + width + widthMargin, moduleY - heightMargin],
|
||||
[moduleX + width + widthMargin, moduleY - height - heightMargin],
|
||||
[moduleX + widthMargin, moduleY - height - heightMargin],
|
||||
]
|
||||
|
||||
let squarePolygon = turf.polygon([square])
|
||||
@ -3029,15 +3094,47 @@ export function useModuleBasicSetting(tabNum) {
|
||||
|
||||
moduleOptions = { ...moduleOptions, fill: module.color, surfaceId: moduleSetupSurface.id, moduleInfo: module }
|
||||
let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon })
|
||||
canvas?.add(tempModule)
|
||||
moduleSetupArray.push(tempModule)
|
||||
moduleGroup.push(tempModule)
|
||||
|
||||
let disjointFromTrestle = checkModuleDisjointSurface(squarePolygon, polygonToTurfPolygon(moduleSetupSurface, true))
|
||||
let isDisjoint = checkModuleDisjointObjects(squarePolygon, containsBatchObjects)
|
||||
|
||||
if (disjointFromTrestle && isDisjoint) {
|
||||
//최초 한번은 그냥 그린다
|
||||
//겹치는지 확인해서 포함된 모듈만 그린다
|
||||
canvas?.add(tempModule)
|
||||
moduleSetupArray.push(tempModule)
|
||||
moduleArray.push(tempModule)
|
||||
canvas.renderAll()
|
||||
|
||||
// ++installedModuleHeightCount
|
||||
|
||||
isInstall = true
|
||||
//마지막에 설치된 모듈의 Y 좌표
|
||||
installedLastHeightCoord = moduleY - height - heightMargin
|
||||
} else {
|
||||
//디버깅용
|
||||
// tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 })
|
||||
// canvas?.add(tempModule)
|
||||
// canvas.renderAll()
|
||||
}
|
||||
}
|
||||
if (isInstall) {
|
||||
++installedModuleHeightCount
|
||||
}
|
||||
}
|
||||
setupModule.push(moduleArray)
|
||||
})
|
||||
}
|
||||
|
||||
const flatRoofLeftFlowSetupModule = (surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) => {
|
||||
const flatRoofLeftFlowSetupModule = (
|
||||
surfaceMaxLines,
|
||||
maxLengthLine,
|
||||
moduleSetupArray,
|
||||
moduleSetupSurface,
|
||||
intvHor,
|
||||
intvVer,
|
||||
containsBatchObjects,
|
||||
) => {
|
||||
checkedModule.forEach((module, index) => {
|
||||
const { width, height } = getModuleWidthHeight(maxLengthLine, moduleSetupSurface, module)
|
||||
const flowLines = getFlowLines(moduleSetupSurface, width)
|
||||
@ -3082,7 +3179,15 @@ export function useModuleBasicSetting(tabNum) {
|
||||
})
|
||||
}
|
||||
|
||||
const flatRoofTopFlowSetupModule = (surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) => {
|
||||
const flatRoofTopFlowSetupModule = (
|
||||
surfaceMaxLines,
|
||||
maxLengthLine,
|
||||
moduleSetupArray,
|
||||
moduleSetupSurface,
|
||||
intvHor,
|
||||
intvVer,
|
||||
containsBatchObjects,
|
||||
) => {
|
||||
checkedModule.forEach((module, index) => {
|
||||
const { width, height } = getModuleWidthHeight(maxLengthLine, moduleSetupSurface, module)
|
||||
const flowLines = getFlowLines(moduleSetupSurface, height)
|
||||
@ -3129,7 +3234,15 @@ export function useModuleBasicSetting(tabNum) {
|
||||
})
|
||||
}
|
||||
|
||||
const flatRoofRightFlowSetupModule = (surfaceMaxLines, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) => {
|
||||
const flatRoofRightFlowSetupModule = (
|
||||
surfaceMaxLines,
|
||||
maxLengthLine,
|
||||
moduleSetupArray,
|
||||
moduleSetupSurface,
|
||||
intvHor,
|
||||
intvVer,
|
||||
containsBatchObjects,
|
||||
) => {
|
||||
checkedModule.forEach((module, index) => {
|
||||
const { width, height } = getModuleWidthHeight(maxLengthLine, moduleSetupSurface, module)
|
||||
const flowLines = getFlowLines(moduleSetupSurface, width)
|
||||
@ -3186,20 +3299,13 @@ export function useModuleBasicSetting(tabNum) {
|
||||
const containsBatchObjects = objectsIncludeSurface(turfModuleSetupSurface) //배치면에 오브젝트(도머, 개구등)이 있는지 확인하는 로직
|
||||
|
||||
const surfaceMaxLines = findSetupSurfaceMaxLines(moduleSetupSurface)
|
||||
const marginWidth = 1
|
||||
const marginHeight = 3
|
||||
const intvHor = 30
|
||||
const intvVer = 10
|
||||
|
||||
canvas.renderAll()
|
||||
|
||||
if (compasDeg >= 0 && compasDeg < 90) {
|
||||
flatRoofDownFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight)
|
||||
} else if (compasDeg >= 90 && compasDeg < 180) {
|
||||
flatRoofLeftFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight)
|
||||
} else if (compasDeg >= 180 && compasDeg < 270) {
|
||||
flatRoofRightFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight)
|
||||
} else {
|
||||
flatRoofTopFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight)
|
||||
}
|
||||
//육지붕은 왼쪽 기준으로 그려진다
|
||||
flatRoofDownFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, intvHor, intvVer, containsBatchObjects)
|
||||
|
||||
const setupedModules = moduleSetupArray.filter((module, index) => {
|
||||
let disjointFromTrestle = checkModuleDisjointSurface(module.turfPoints, turfModuleSetupSurface)
|
||||
|
||||
@ -3536,3 +3536,18 @@ export const calcLineActualSize = (points, degree) => {
|
||||
}
|
||||
return Big(planeSize).pow(2).plus(height.pow(2)).sqrt().abs().round().toNumber()
|
||||
}
|
||||
|
||||
export const createLinesFromPolygon = (points) => {
|
||||
const lines = []
|
||||
for (let i = 0; i < points.length; i++) {
|
||||
const nextIndex = (i + 1) % points.length
|
||||
const line = new fabric.Line([points[i].x, points[i].y, points[nextIndex].x, points[nextIndex].y], {
|
||||
stroke: 'red',
|
||||
strokeWidth: 2,
|
||||
selectable: false,
|
||||
evented: false,
|
||||
})
|
||||
lines.push(line)
|
||||
}
|
||||
return lines
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user