지붕 모양 변경 작업 중

This commit is contained in:
Jaeyoung Lee 2024-10-18 10:29:31 +09:00
parent 55d4aa5347
commit 0bc0e73a10
4 changed files with 197 additions and 97 deletions

View File

@ -63,6 +63,7 @@ export const LINE_TYPE = {
HIPANDGABLE: 'hipAndGable',
JERKINHEAD: 'jerkinhead',
SHED: 'shed',
ETC: 'etc',
},
SUBLINE: {
/**

View File

@ -4,7 +4,7 @@ import { useCanvas } from '@/hooks/useCanvas'
import { useEffect, useRef, useState } from 'react'
import { v4 as uuidv4 } from 'uuid'
import { useMode } from '@/hooks/useMode'
import { Mode } from '@/common/common'
import { LINE_TYPE, Mode } from '@/common/common'
import { Button, Input } from '@nextui-org/react'
import RangeSlider from './ui/RangeSlider'
import { useRecoilState, useRecoilValue } from 'recoil'
@ -39,7 +39,7 @@ import QEmptyContextMenu from '@/components/common/context-menu/QEmptyContextMen
import InitSettingsModal from './InitSettingsModal'
import GridSettingsModal from './GridSettingsModal'
import { SurfaceShapeModal } from '@/components/ui/SurfaceShape'
import { drawDirectionStringToArrow } from '@/util/qpolygon-utils'
import { changeHipAndGableRoof, drawDirectionStringToArrow } from '@/util/qpolygon-utils'
import ThumbnailList from '@/components/ui/ThumbnailLIst'
import ObjectPlacement from '@/components/ui/ObjectPlacement'
import { globalLocaleStore } from '@/store/localeAtom'
@ -431,7 +431,7 @@ export default function Roof2(props) {
{ x: 450, y: 850 },
]
const polygon = new QPolygon(rectangleType2, {
const polygon = new QPolygon(rectangleType1, {
fill: 'transparent',
stroke: 'green',
strokeWidth: 1,
@ -672,13 +672,14 @@ export default function Roof2(props) {
canvas?.renderAll()
}
const setAllGableRoof = () => {
const setGableRoof = () => {
let offset = Number(prompt('gable roof offset', '50'))
if (!isNaN(offset) && offset > 0) {
const polygon = canvas?.getObjects()
console.log('gable roof offset : ', offset)
console.log('polygon : ', polygon)
changeAllGableRoof(polygon, offset, canvas)
const polygon = canvas?.getObjects().find((obj) => obj.name === 'roof')
const currentRoof = polygon.lines[3]
currentRoof.attributes.type = LINE_TYPE.WALLLINE.HIPANDGABLE
currentRoof.attributes.width = offset
changeHipAndGableRoof(currentRoof, canvas)
} else {
alert('offset 은 0 보다 커야 함')
}
@ -802,16 +803,28 @@ export default function Roof2(props) {
<Button className="m-1 p-2" onClick={makePolygon}>
다각형 추가
</Button>
{templateType === 0 && (
<>
<Button className="m-1 p-2" onClick={makeQPolygon}>
QPolygon
</Button>
</>
)}
<Button className={'m-1 p-2'} onClick={setAllGableRoof}>
{/*{templateType === 0 && (*/}
{/* <>*/}
<Button className="m-1 p-2" onClick={makeQPolygon}>
QPolygon
</Button>
{/* </>*/}
{/*)}*/}
<Button className={'m-1 p-2'} onClick={null}>
용마루지붕
</Button>
<Button className={'m-1 p-2'} onClick={setGableRoof}>
팔작지붕
</Button>
<Button className={'m-1 p-2'} onClick={null}>
박공지붕
</Button>
<Button className={'m-1 p-2'} onClick={null}>
반절처지붕
</Button>
<Button className={'m-1 p-2'} onClick={null}>
벽지붕
</Button>
<Button className="m-1 p-2" onClick={() => saveImage(uuidv4(), userId, setThumbnails)}>
저장
</Button>

View File

@ -36,10 +36,7 @@ import { QPolygon } from '@/components/fabric/QPolygon'
import offsetPolygon from '@/util/qpolygon-utils'
import { isObjectNotEmpty } from '@/util/common-utils'
import * as turf from '@turf/turf'
import { INPUT_TYPE, Mode } from '@/common/common'
import { m } from 'framer-motion'
import { set } from 'react-hook-form'
import { FaWineGlassEmpty } from 'react-icons/fa6'
import { INPUT_TYPE, LINE_TYPE, Mode } from '@/common/common'
export function useMode() {
const [mode, setMode] = useRecoilState(modeState)
@ -1509,6 +1506,43 @@ export function useMode() {
* 지붕 외곽선 생성 polygon을 입력받아 만들기
*/
const handleOuterlinesTest2 = (polygon, offset = 50) => {
console.log('polygon : ', polygon)
// TODO [ljyoung] : offset 입력 처리 후 제거 해야함.
polygon.lines.forEach((line, index) => {
line.attributes = {
type: LINE_TYPE.WALLLINE.EAVES,
offset: 40,
width: 50,
pitch: 4,
sleeve: true,
}
/*if (index === 1 || index === 3) {
line.attributes = {
type: LINE_TYPE.WALLLINE.WALL,
offset: 0, //출폭
width: 30, //폭
pitch: 4, //구배
sleeve: true, //소매
}
} else if (index === 0) {
line.attributes = {
type: LINE_TYPE.WALLLINE.EAVES,
offset: 0,
width: 50,
pitch: 4,
sleeve: true,
}
} else {
line.attributes = {
type: LINE_TYPE.WALLLINE.EAVES,
offset: 40,
width: 50,
pitch: 4,
sleeve: true,
}
}*/
})
const roof = drawRoofPolygon(polygon) //지붕 그리기
roof.drawHelpLine()
// roof.divideLine()
@ -1706,6 +1740,7 @@ export function useMode() {
offset: wall.lines[index].attributes.offset,
width: wall.lines[index].attributes.width,
pitch: wall.lines[index].attributes.pitch,
sleeve: wall.lines[index].attributes.sleeve || false,
}
})

View File

@ -2030,7 +2030,6 @@ const connectLinePoint = (polygon) => {
}
const modifyRidge = (roof, canvas) => {
const roofLines = roof.lines
const ridgeLines = canvas?.getObjects().filter((object) => object.name === 'ridgeLine' && object.attributes.roofId === roof.id)
const hipLines = canvas?.getObjects().filter((object) => object.name === 'hipLine' && object.attributes.roofId === roof.id)
@ -2041,7 +2040,6 @@ const modifyRidge = (roof, canvas) => {
let currentRoof = roof.lines
.filter((roofLine) => roofLine.attributes !== undefined && roofLine.attributes.ridgeCoordinate !== undefined)
.find((roofLine) => roofLine.attributes.ridgeCoordinate.x1 === ridge.x1 && roofLine.attributes.ridgeCoordinate.y1 === ridge.y1)
console.log('1 currentRoof : ', currentRoof)
if (currentRoof === undefined) {
currentRoof = roof.lines.find(
(roofLine) =>
@ -2058,7 +2056,6 @@ const modifyRidge = (roof, canvas) => {
currentRoof.attributes.ridgeCoordinate = { x1: ridge.x1, y1: ridge.y1 }
}
}
console.log('2 currentRoof : ', currentRoof)
if (currentRoof !== undefined) {
switch (currentRoof.attributes.type) {
case LINE_TYPE.WALLLINE.EAVES:
@ -2067,7 +2064,7 @@ const modifyRidge = (roof, canvas) => {
changeGableRoof(roof.id, currentRoof, canvas)
break
case LINE_TYPE.WALLLINE.HIPANDGABLE:
changeHipAndGableRoof(roof.id, currentRoof, canvas)
changeHipAndGableRoof(currentRoof, canvas)
break
case LINE_TYPE.WALLLINE.JERKINHEAD:
changeJerkInHeadRoof(roof.id, currentRoof, canvas)
@ -2082,7 +2079,6 @@ const modifyRidge = (roof, canvas) => {
let currentRoof = roof.lines
.filter((roofLine) => roofLine.attributes !== undefined && roofLine.attributes.ridgeCoordinate !== undefined)
.find((roofLine) => roofLine.attributes.ridgeCoordinate.x1 === ridge.x2 && roofLine.attributes.ridgeCoordinate.y1 === ridge.y2)
console.log('3 currentRoof : ', currentRoof)
if (currentRoof === undefined) {
currentRoof = roof.lines.find(
(roofLine) =>
@ -2099,7 +2095,6 @@ const modifyRidge = (roof, canvas) => {
currentRoof.attributes.ridgeCoordinate = { x1: ridge.x2, y1: ridge.y2 }
}
}
console.log('4 currentRoof : ', currentRoof)
if (currentRoof !== undefined) {
switch (currentRoof.attributes.type) {
case LINE_TYPE.WALLLINE.EAVES:
@ -2108,7 +2103,7 @@ const modifyRidge = (roof, canvas) => {
changeGableRoof(roof.id, currentRoof, canvas)
break
case LINE_TYPE.WALLLINE.HIPANDGABLE:
changeHipAndGableRoof(roof.id, currentRoof, canvas)
changeHipAndGableRoof(currentRoof, canvas)
break
case LINE_TYPE.WALLLINE.JERKINHEAD:
changeJerkInHeadRoof(roof.id, currentRoof, canvas)
@ -2220,12 +2215,12 @@ export const changeGableRoof = (roofId, currentRoof, canvas) => {
/**
* 팔작지붕으로 변경
* @param roofId
* @param currentRoof
* @param canvas
*/
export const changeHipAndGableRoof = (roofId, currentRoof, canvas) => {
export const changeHipAndGableRoof = (currentRoof, canvas) => {
if (currentRoof.attributes.type === LINE_TYPE.WALLLINE.HIPANDGABLE) {
const roofId = currentRoof.attributes.roofId
const roof = canvas?.getObjects().find((object) => object.name === 'roof' && object.id === roofId)
let hipLines = canvas?.getObjects().filter((object) => object.name === 'hipLine' && object.attributes.roofId === roofId)
let ridgeLines = canvas?.getObjects().filter((object) => object.name === 'ridgeLine' && object.attributes.roofId === roofId)
@ -2239,7 +2234,11 @@ export const changeHipAndGableRoof = (roofId, currentRoof, canvas) => {
(hip) => (hip.x1 === currentRoof.x1 && hip.y1 === currentRoof.y1) || (hip.x1 === currentRoof.x2 && hip.y1 === currentRoof.y2),
)
if (ridgeLines.length > 0) {
hipLines.forEach((hip) => canvas?.remove(hip))
console.log(canvas?.getObjects().find((object) => object.attributes !== undefined && object.attributes.roofId === roofId))
/*if (ridgeLines.length > 0) {
const ridge = ridgeLines[0]
let midX = (currentRoof.x1 + currentRoof.x2) / 2
let midY = (currentRoof.y1 + currentRoof.y2) / 2
@ -2310,7 +2309,7 @@ export const changeHipAndGableRoof = (roofId, currentRoof, canvas) => {
roof.innerLines.push(hipLine)
})
}
}
}*/
}
}
@ -2426,8 +2425,13 @@ export const changeJerkInHeadRoof = (roofId, currentRoof, canvas) => {
}
}
/**
* 벽지붕으로 변경
* @param roofId
* @param currentRoof
* @param canvas
*/
const changeWallRoof = (roofId, currentRoof, canvas) => {
console.log('roofId : ', roofId)
let roof = canvas?.getObjects().find((object) => object.name === 'roof' && object.id === roofId)
const roofLines = roof.lines
let prevRoof, nextRoof
@ -2444,6 +2448,10 @@ const changeWallRoof = (roofId, currentRoof, canvas) => {
let hipLines = canvas?.getObjects().filter((object) => object.name === 'hipLine' && object.attributes.roofId === roofId)
let ridgeLines = canvas?.getObjects().filter((object) => object.name === 'ridgeLine' && object.attributes.roofId === roofId)
if (wallLine.length > 0) {
wallLine = wallLine[0]
}
ridgeLines = ridgeLines.filter(
(ridge) =>
(ridge.x1 === currentRoof.attributes.ridgeCoordinate.x1 && ridge.y1 === currentRoof.attributes.ridgeCoordinate.y1) ||
@ -2453,8 +2461,8 @@ const changeWallRoof = (roofId, currentRoof, canvas) => {
(hip) => (hip.x1 === currentRoof.x1 && hip.y1 === currentRoof.y1) || (hip.x1 === currentRoof.x2 && hip.y1 === currentRoof.y2),
)
const wallMidX = (wallLine[0].x1 + wallLine[0].x2) / 2
const wallMidY = (wallLine[0].y1 + wallLine[0].y2) / 2
const wallMidX = (wallLine.x1 + wallLine.x2) / 2
const wallMidY = (wallLine.y1 + wallLine.y2) / 2
const roofMidX = (currentRoof.x1 + currentRoof.x2) / 2
const roofMidY = (currentRoof.y1 + currentRoof.y2) / 2
@ -2482,7 +2490,88 @@ const changeWallRoof = (roofId, currentRoof, canvas) => {
y2: nextRoof.y2,
})
reDrawPolygon(roof, canvas)
if (currentRoof.attributes.sleeve && prevRoof.attributes.offset > 0 && nextRoof.attributes.offset > 0) {
const prevSignX = Math.sign(prevRoof.x1 - prevRoof.x2)
const prevSignY = Math.sign(prevRoof.y1 - prevRoof.y2)
const nextSignX = Math.sign(nextRoof.x1 - nextRoof.x2)
const nextSignY = Math.sign(nextRoof.y1 - nextRoof.y2)
const prevWidthX = prevSignX === 0 ? 0 : prevSignX * currentRoof.attributes.width
const prevWidthY = prevSignY === 0 ? 0 : prevSignY * currentRoof.attributes.width
const nextWidthX = nextSignX === 0 ? 0 : nextSignX * currentRoof.attributes.width
const nextWidthY = nextSignY === 0 ? 0 : nextSignY * currentRoof.attributes.width
const prevX2 = prevRoof.x2 - prevWidthX
const prevY2 = prevRoof.y2 - prevWidthY
const nextX1 = nextRoof.x1 + nextWidthX
const nextY1 = nextRoof.y1 + nextWidthY
currentRoof.set({
x1: wallLine.x1,
y1: wallLine.y1,
x2: wallLine.x2,
y2: wallLine.y2,
})
prevRoof.set({
x1: prevRoof.x1,
y1: prevRoof.y1,
x2: prevX2,
y2: prevY2,
})
nextRoof.set({
x1: nextX1,
y1: nextY1,
x2: nextRoof.x2,
y2: nextRoof.y2,
})
const addPrevWallLine1 = new QLine([prevX2, prevY2, wallLine.x1 - prevWidthX, wallLine.y1 - prevWidthY], {
fontSize: roof.fontSize,
stroke: 'red',
strokeWidth: 1,
name: 'roofLine',
attributes: { roofId: roofId, type: LINE_TYPE.WALLLINE.ETC },
})
const addPrevWallLine2 = new QLine(
[addPrevWallLine1.x2, addPrevWallLine1.y2, addPrevWallLine1.x2 + prevWidthX, addPrevWallLine1.y2 + prevWidthY],
{
fontSize: roof.fontSize,
stroke: 'cyan',
strokeWidth: 1,
name: 'roofLine',
attributes: { roofId: roofId, type: LINE_TYPE.WALLLINE.ETC },
},
)
const addNextWallLine1 = new QLine([wallLine.x2, wallLine.y2, wallLine.x2 + nextWidthX, wallLine.y2 + nextWidthY], {
fontSize: roof.fontSize,
stroke: 'green',
strokeWidth: 1,
name: 'roofLine',
attributes: { roofId: roofId, type: LINE_TYPE.WALLLINE.ETC },
})
const addNextWallLine2 = new QLine([addNextWallLine1.x2, addNextWallLine1.y2, nextX1, nextY1], {
fontSize: roof.fontSize,
stroke: 'red',
strokeWidth: 1,
name: 'roofLine',
attributes: { roofId: roofId, type: LINE_TYPE.WALLLINE.ETC },
})
canvas?.renderAll()
const prevIndex = roof.lines.indexOf(prevRoof) + 1
roof.lines.splice(prevIndex, 0, addPrevWallLine1, addPrevWallLine2)
const nextIndex = roof.lines.indexOf(currentRoof) + 1
roof.lines.splice(nextIndex, 0, addNextWallLine1, addNextWallLine2)
}
roof = reDrawPolygon(roof, canvas)
console.log('roof : ', roof.lines)
if (ridgeLines.length > 0) {
const ridge = ridgeLines[0]
@ -2508,72 +2597,31 @@ const changeWallRoof = (roofId, currentRoof, canvas) => {
y2: ridge.y2 - diffY,
})
}
}
console.log('hipLines : ', hipLines)
let hip1 = new QLine([currentRoof.x1, currentRoof.y1, wallMidX, wallMidY], {
fontSize: roof.fontSize,
stroke: 'red',
strokeWidth: 1,
name: 'hipLine',
attributes: { roofId: roof.id, currentRoofId: currentRoof.id, planeSize: currentRoof.length, actualSize: currentRoof.length },
})
let hip2 = new QLine([currentRoof.x2, currentRoof.y2, wallMidX, wallMidY], {
fontSize: roof.fontSize,
stroke: 'red',
strokeWidth: 1,
name: 'hipLine',
attributes: { roofId: roof.id, currentRoofId: currentRoof.id, planeSize: currentRoof.length, actualSize: currentRoof.length },
})
canvas?.add(hip1)
canvas?.add(hip2)
}
if (hipLines.length > 0) {
hipLines.forEach((hip) => {
const diffX = hip.x1 - wallMidX
const diffY = hip.y1 - wallMidY
console.log('diffX : ', diffX, ' diffY : ', diffY)
hip.set({
x1: hip.x1,
y1: hip.y1,
x2: wallMidX,
y2: wallMidY,
})
canvas?.remove(hip)
})
}
}
export const changeAllHipAndGableRoof = (polygon, offset, canvas) => {
const roof = polygon.filter((p) => p.name === 'roof')[0] // 지붕
const roofLines = roof.lines // 지붕의 라인
const ridges = roof.ridges // 마루의 라인
const hips = roof.hips // 추녀마루의 라인
console.log('roofLines : ', roofLines)
ridges.forEach((ridge) => {
let ridgeHip1 = hips.filter((hip) => hip.x2 === ridge.x1 && hip.y2 === ridge.y1)
let ridgeHip2 = hips.filter((hip) => hip.x2 === ridge.x2 && hip.y2 === ridge.y2)
let gableLines = []
if (ridgeHip1.length > 1) {
let x1 = ridgeHip1[0].x1,
y1 = ridgeHip1[0].y1,
x2 = ridgeHip1[1].x1,
y2 = ridgeHip1[1].y1
roofLines.filter((roofLine) => {
if (
(roofLine.x1 === x1 && roofLine.y1 === y1 && roofLine.x2 === x2 && roofLine.y2 === y2) ||
(roofLine.x1 === x2 && roofLine.y1 === y2 && roofLine.x2 === x1 && roofLine.y2 === y1)
) {
gableLines.push(setHipAndGableRoof(roof, ridge, ridgeHip1[0], ridgeHip1[1], offset, canvas))
}
})
}
if (ridgeHip2.length > 1) {
let x1 = ridgeHip2[0].x1,
y1 = ridgeHip2[0].y1,
x2 = ridgeHip2[1].x1,
y2 = ridgeHip2[1].y1
roofLines.filter((roofLine) => {
if (
(roofLine.x1 === x1 && roofLine.y1 === y1 && roofLine.x2 === x2 && roofLine.y2 === y2) ||
(roofLine.x1 === x2 && roofLine.y1 === y2 && roofLine.x2 === x1 && roofLine.y2 === y1)
) {
gableLines.push(setHipAndGableRoof(roof, ridge, ridgeHip2[0], ridgeHip2[1], offset, canvas))
}
})
}
gableLines.forEach((gableLine) => {
roof.innerLines.push(gableLine)
})
})
// splitPolygonWithLines(roof)
}
/**
* 모임지붕 -> 팔작지붕 변경
* @param roof
@ -2860,7 +2908,7 @@ const reDrawPolygon = (polygon, canvas) => {
let point = []
lines.forEach((line) => point.push({ x: line.x1, y: line.y1 }))
console.log('point : ', point)
canvas?.remove(polygon)
const newPolygon = new QPolygon(point, {
id: polygon.id,
@ -2877,14 +2925,17 @@ const reDrawPolygon = (polygon, canvas) => {
newLines.forEach((line, index) => {
lines.forEach((l, i) => {
if (index === i) {
if (line.x1 === l.x1 && line.y1 === l.y1) {
line.id = l.id
line.attributes = l.attributes
}
})
})
canvas?.add(newPolygon)
canvas?.remove(polygon)
canvas?.renderAll()
return newPolygon
}
function arePointsEqual(point1, point2) {