Compare commits

..

No commits in common. "23b8aa7fa74eb2f2ae1cb05b07fbfaafba2d2bda" and "28d26511de36f6d8e41cf2370f5a7de3d051c7aa" have entirely different histories.

6 changed files with 779 additions and 1499 deletions

1
.gitignore vendored
View File

@ -43,4 +43,3 @@ yarn.lock
package-lock.json package-lock.json
pnpm-lock.yaml pnpm-lock.yaml
certificates certificates
.ai

View File

@ -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",

View File

@ -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('패턴 지붕')

View File

@ -30,8 +30,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)
@ -451,22 +449,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 {

View File

@ -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.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
// 매핑된 innerLine의 attributes를 변경 (교차점 계산 전에 적용)
innerLineMapping.forEach((polygonLine, innerLine) => {
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
})
} }
} }
}) })
@ -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.length > 0 ? path : null; return path
} }
// 최종 함수 // 최종 함수
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인 경우에만 가능

File diff suppressed because it is too large Load Diff