삭제
This commit is contained in:
parent
127c2e0109
commit
338933940e
@ -1,387 +0,0 @@
|
|||||||
import { useEffect } from 'react'
|
|
||||||
import { useRecoilState } from 'recoil'
|
|
||||||
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
|
|
||||||
import Big from 'big.js'
|
|
||||||
import { isSamePoint, toGeoJSON } from '@/util/qpolygon-utils'
|
|
||||||
import { SkeletonBuilder } from '@/lib/skeletons'
|
|
||||||
import {
|
|
||||||
preprocessPolygonCoordinates,
|
|
||||||
findOppositeLine,
|
|
||||||
createOrderedBasePoints,
|
|
||||||
createInnerLinesFromSkeleton
|
|
||||||
} from '@/util/skeleton-utils'
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default function useSkeleton(canvas, roofId, textMode = false) {
|
|
||||||
// 2. 스켈레톤 생성 및 그리기
|
|
||||||
//처마
|
|
||||||
if (!canvas) {
|
|
||||||
console.warn('Canvas is not available');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let roof = canvas?.getObjects().find((object) => object.id === roofId)
|
|
||||||
|
|
||||||
if (!roof) {
|
|
||||||
console.warn(`Roof with id ${roofId} not found`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!roof.points || roof.points.length < 3) {
|
|
||||||
console.warn('Roof points are invalid');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const eavesType = [LINE_TYPE.WALLLINE.EAVES, LINE_TYPE.WALLLINE.HIPANDGABLE]
|
|
||||||
const gableType = [LINE_TYPE.WALLLINE.GABLE, LINE_TYPE.WALLLINE.JERKINHEAD]
|
|
||||||
|
|
||||||
/** 외벽선 */
|
|
||||||
const wall = canvas.getObjects().find((object) => object.name === POLYGON_TYPE.WALL && object.attributes.roofId === roofId)
|
|
||||||
//const baseLines = wall.baseLines.filter((line) => line.attributes.planeSize > 0)
|
|
||||||
|
|
||||||
const baseLines = canvas.getObjects().filter((object) => object.name === 'baseLine' && object.parentId === roofId) || [];
|
|
||||||
const baseLinePoints = baseLines.map((line) => ({x:line.left, y:line.top}));
|
|
||||||
|
|
||||||
const outerLines = canvas.getObjects().filter((object) => object.name === 'outerLinePoint') || [];
|
|
||||||
const outerLinePoints = outerLines.map((line) => ({x:line.left, y:line.top}))
|
|
||||||
|
|
||||||
const hipLines = canvas.getObjects().filter((object) => object.name === 'hip' && object.parentId === roofId) || [];
|
|
||||||
const ridgeLines = canvas.getObjects().filter((object) => object.name === 'ridge' && object.parentId === roofId) || [];
|
|
||||||
|
|
||||||
//const skeletonLines = [];
|
|
||||||
// 1. 지붕 폴리곤 좌표 전처리
|
|
||||||
const coordinates = preprocessPolygonCoordinates(roof.points);
|
|
||||||
if (coordinates.length < 3) {
|
|
||||||
console.warn("Polygon has less than 3 unique points. Cannot generate skeleton.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const moveFlowLine = roof.moveFlowLine || 0; // Provide a default value
|
|
||||||
const moveUpDown = roof.moveUpDown || 0; // Provide a default value
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let points = roof.points;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//마루이동
|
|
||||||
if (moveFlowLine !== 0 || moveUpDown !== 0) {
|
|
||||||
const movingLineFromSkeleton = (roofId, canvas) => {
|
|
||||||
if (!canvas) {
|
|
||||||
console.warn('Canvas is not available in movingLineFromSkeleton');
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let roof = canvas?.getObjects().find((object) => object.id === roofId)
|
|
||||||
|
|
||||||
if (!roof) {
|
|
||||||
console.warn(`Roof with id ${roofId} not found in movingLineFromSkeleton`);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let moveDirection = roof.moveDirect;
|
|
||||||
let moveFlowLine = roof.moveFlowLine??0;
|
|
||||||
let moveUpDown = roof.moveUpDown??0;
|
|
||||||
const getSelectLine = () => roof.moveSelectLine;
|
|
||||||
const selectLine = getSelectLine();
|
|
||||||
|
|
||||||
if (!selectLine || !selectLine.startPoint || !selectLine.endPoint) {
|
|
||||||
console.warn('SelectLine is not available');
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let movePosition = roof.movePosition;
|
|
||||||
|
|
||||||
const startPoint = selectLine.startPoint
|
|
||||||
const endPoint = selectLine.endPoint
|
|
||||||
const orgRoofPoints = roof.points; // orgPoint를 orgPoints로 변경
|
|
||||||
|
|
||||||
if (!canvas.skeleton || !canvas.skeleton.Edges) {
|
|
||||||
console.warn('Skeleton edges are not available');
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const oldPoints = canvas?.skeleton.lastPoints ?? orgRoofPoints // 여기도 변경
|
|
||||||
const oppositeLine = findOppositeLine(canvas.skeleton.Edges, startPoint, endPoint, oldPoints);
|
|
||||||
|
|
||||||
const wall = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.WALL && obj.attributes.roofId === roofId)
|
|
||||||
|
|
||||||
if (!wall || !wall.baseLines) {
|
|
||||||
console.warn('Wall or baseLines are not available');
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseLines = wall.baseLines
|
|
||||||
roof.basePoints = createOrderedBasePoints(roof.points, baseLines)
|
|
||||||
|
|
||||||
const skeletonPolygon = canvas.getObjects().filter((object) => object.skeletonType === 'polygon' && object.parentId === roofId)
|
|
||||||
const skeletonLines = canvas.getObjects().filter((object) => object.skeletonType === 'line' && object.parentId === roofId)
|
|
||||||
|
|
||||||
if (oppositeLine) {
|
|
||||||
console.log('Opposite line found:', oppositeLine);
|
|
||||||
} else {
|
|
||||||
console.log('No opposite line found');
|
|
||||||
}
|
|
||||||
|
|
||||||
if(moveFlowLine !== 0) {
|
|
||||||
return oldPoints.map((point, index) => {
|
|
||||||
console.log('Point:', point);
|
|
||||||
const newPoint = { ...point };
|
|
||||||
const absMove = Big(moveFlowLine).times(2).div(10);
|
|
||||||
|
|
||||||
console.log('skeletonBuilder moveDirection:', moveDirection);
|
|
||||||
|
|
||||||
switch (moveDirection) {
|
|
||||||
case 'left':
|
|
||||||
// Move left: decrease X
|
|
||||||
if (moveFlowLine !== 0) {
|
|
||||||
for (const line of oppositeLine) {
|
|
||||||
if (line.position === 'left') {
|
|
||||||
if (isSamePoint(newPoint, line.start)) {
|
|
||||||
newPoint.x = Big(line.start.x).plus(absMove).toNumber();
|
|
||||||
} else if (isSamePoint(newPoint, line.end)) {
|
|
||||||
newPoint.x = Big(line.end.x).plus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
} else if (moveUpDown !== 0) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 'right':
|
|
||||||
for (const line of oppositeLine) {
|
|
||||||
if (line.position === 'right') {
|
|
||||||
if (isSamePoint(newPoint, line.start)) {
|
|
||||||
newPoint.x = Big(line.start.x).minus(absMove).toNumber();
|
|
||||||
} else if (isSamePoint(newPoint, line.end)) {
|
|
||||||
newPoint.x = Big(line.end.x).minus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
break
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 'up':
|
|
||||||
// Move up: decrease Y (toward top of screen)
|
|
||||||
|
|
||||||
for (const line of oppositeLine) {
|
|
||||||
if (line.position === 'top') {
|
|
||||||
if (isSamePoint(newPoint, line.start)) {
|
|
||||||
newPoint.y = Big(line.start.y).minus(absMove).toNumber();
|
|
||||||
} else if (isSamePoint(newPoint, line.end)) {
|
|
||||||
newPoint.y = Big(line.end.y).minus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 'down':
|
|
||||||
// Move down: increase Y (toward bottom of screen)
|
|
||||||
for (const line of oppositeLine) {
|
|
||||||
|
|
||||||
if (line.position === 'bottom') {
|
|
||||||
|
|
||||||
console.log('oldPoint:', point);
|
|
||||||
|
|
||||||
if (isSamePoint(newPoint, line.start)) {
|
|
||||||
newPoint.y = Big(line.start.y).minus(absMove).toNumber();
|
|
||||||
|
|
||||||
} else if (isSamePoint(newPoint, line.end)) {
|
|
||||||
newPoint.y = Big(line.end.y).minus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default :
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('newPoint:', newPoint);
|
|
||||||
//baseline 변경
|
|
||||||
return newPoint;
|
|
||||||
})
|
|
||||||
} else if(moveUpDown !== 0) {
|
|
||||||
|
|
||||||
const position = movePosition //result.position;
|
|
||||||
const absMove = Big(moveUpDown).times(1).div(10);
|
|
||||||
const modifiedStartPoints = [];
|
|
||||||
// oldPoints를 복사해서 새로운 points 배열 생성
|
|
||||||
let newPoints = oldPoints.map(point => ({...point}));
|
|
||||||
|
|
||||||
// selectLine과 일치하는 baseLines 찾기
|
|
||||||
const matchingLines = baseLines
|
|
||||||
.map((line, index) => ({ ...line, findIndex: index }))
|
|
||||||
.filter(line =>
|
|
||||||
(isSamePoint(line.startPoint, selectLine.startPoint) &&
|
|
||||||
isSamePoint(line.endPoint, selectLine.endPoint)) ||
|
|
||||||
(isSamePoint(line.startPoint, selectLine.endPoint) &&
|
|
||||||
isSamePoint(line.endPoint, selectLine.startPoint))
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
matchingLines.forEach(line => {
|
|
||||||
const originalStartPoint = line.startPoint;
|
|
||||||
const originalEndPoint = line.endPoint;
|
|
||||||
const offset = line.attributes.offset
|
|
||||||
// 새로운 좌표 계산
|
|
||||||
let newStartPoint = {...originalStartPoint};
|
|
||||||
let newEndPoint = {...originalEndPoint};
|
|
||||||
|
|
||||||
|
|
||||||
// 원본 라인 업데이트
|
|
||||||
// newPoints 배열에서 일치하는 포인트들을 찾아서 업데이트
|
|
||||||
console.log('absMove::', absMove);
|
|
||||||
newPoints.forEach((point, index) => {
|
|
||||||
if(position === 'bottom'){
|
|
||||||
if (moveDirection === 'in') {
|
|
||||||
if(isSamePoint(roof.basePoints[index], originalStartPoint) || isSamePoint(roof.basePoints[index], originalEndPoint)) {
|
|
||||||
point.y = Big(point.y).minus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
// if (isSamePoint(roof.basePoints[index], originalEndPoint)) {
|
|
||||||
// point.y = Big(point.y).minus(absMove).toNumber();
|
|
||||||
// }
|
|
||||||
}else if (moveDirection === 'out'){
|
|
||||||
if(isSamePoint(roof.basePoints[index], originalStartPoint) || isSamePoint(roof.basePoints[index], originalEndPoint)) {
|
|
||||||
point.y = Big(point.y).plus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
// if (isSamePoint(roof.basePoints[index], originalEndPoint)) {
|
|
||||||
// point.y = Big(point.y).plus(absMove).toNumber();
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
}else if (position === 'top'){
|
|
||||||
if(moveDirection === 'in'){
|
|
||||||
if(isSamePoint(roof.basePoints[index], originalStartPoint)) {
|
|
||||||
point.y = Big(point.y).plus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
if (isSamePoint(roof.basePoints[index], originalEndPoint)) {
|
|
||||||
point.y = Big(point.y).plus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
}else if(moveDirection === 'out'){
|
|
||||||
if(isSamePoint(roof.basePoints[index], originalStartPoint)) {
|
|
||||||
point.y = Big(point.y).minus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
if (isSamePoint(roof.basePoints[index], originalEndPoint)) {
|
|
||||||
point.y = Big(point.y).minus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}else if(position === 'left'){
|
|
||||||
if(moveDirection === 'in'){
|
|
||||||
if(isSamePoint(roof.basePoints[index], originalStartPoint) || isSamePoint(roof.basePoints[index], originalEndPoint)) {
|
|
||||||
point.x = Big(point.x).plus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
// if (isSamePoint(roof.basePoints[index], originalEndPoint)) {
|
|
||||||
// point.x = Big(point.x).plus(absMove).toNumber();
|
|
||||||
// }
|
|
||||||
}else if(moveDirection === 'out'){
|
|
||||||
if(isSamePoint(roof.basePoints[index], originalStartPoint) || isSamePoint(roof.basePoints[index], originalEndPoint)) {
|
|
||||||
point.x = Big(point.x).minus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
// if (isSamePoint(roof.basePoints[index], originalEndPoint)) {
|
|
||||||
// point.x = Big(point.x).minus(absMove).toNumber();
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
}else if(position === 'right'){
|
|
||||||
if(moveDirection === 'in'){
|
|
||||||
if(isSamePoint(roof.basePoints[index], originalStartPoint)) {
|
|
||||||
point.x = Big(point.x).minus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
if (isSamePoint(roof.basePoints[index], originalEndPoint)) {
|
|
||||||
point.x = Big(point.x).minus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
}else if(moveDirection === 'out'){
|
|
||||||
if(isSamePoint(roof.basePoints[index], originalStartPoint)) {
|
|
||||||
point.x = Big(point.x).plus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
if (isSamePoint(roof.basePoints[index], originalEndPoint)) {
|
|
||||||
point.x = Big(point.x).plus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// 원본 baseLine도 업데이트
|
|
||||||
line.startPoint = newStartPoint;
|
|
||||||
line.endPoint = newEndPoint;
|
|
||||||
});
|
|
||||||
return newPoints;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const result = movingLineFromSkeleton(roofId, canvas);
|
|
||||||
if (result) {
|
|
||||||
points = result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
console.log('points:', points);
|
|
||||||
const geoJSONPolygon = toGeoJSON(points)
|
|
||||||
|
|
||||||
try {
|
|
||||||
// SkeletonBuilder는 닫히지 않은 폴리곤을 기대하므로 마지막 점 제거
|
|
||||||
geoJSONPolygon.pop()
|
|
||||||
const skeleton = SkeletonBuilder.BuildFromGeoJSON([[geoJSONPolygon]])
|
|
||||||
|
|
||||||
// 스켈레톤 데이터를 기반으로 내부선 생성
|
|
||||||
roof.innerLines = roof.innerLines || [];
|
|
||||||
roof.innerLines = createInnerLinesFromSkeleton(roofId, canvas, skeleton, textMode)
|
|
||||||
|
|
||||||
// 캔버스에 스켈레톤 상태 저장
|
|
||||||
if (!canvas.skeletonStates) {
|
|
||||||
canvas.skeletonStates = {}
|
|
||||||
canvas.skeletonLines = []
|
|
||||||
}
|
|
||||||
canvas.skeletonStates[roofId] = true
|
|
||||||
canvas.skeletonLines = [];
|
|
||||||
canvas.skeletonLines.push(...roof.innerLines)
|
|
||||||
roof.skeletonLines = canvas.skeletonLines;
|
|
||||||
|
|
||||||
const cleanSkeleton = {
|
|
||||||
Edges: skeleton.Edges.map(edge => ({
|
|
||||||
X1: edge.Edge.Begin.X,
|
|
||||||
Y1: edge.Edge.Begin.Y,
|
|
||||||
X2: edge.Edge.End.X,
|
|
||||||
Y2: edge.Edge.End.Y,
|
|
||||||
Polygon: edge.Polygon,
|
|
||||||
|
|
||||||
// Add other necessary properties, but skip circular references
|
|
||||||
})),
|
|
||||||
roofId: roofId,
|
|
||||||
// Add other necessary top-level properties
|
|
||||||
};
|
|
||||||
canvas.skeleton = [];
|
|
||||||
canvas.skeleton = cleanSkeleton
|
|
||||||
canvas.skeleton.lastPoints = points
|
|
||||||
canvas.set("skeleton", cleanSkeleton);
|
|
||||||
canvas.renderAll()
|
|
||||||
|
|
||||||
|
|
||||||
console.log('skeleton rendered.', canvas);
|
|
||||||
} catch (e) {
|
|
||||||
console.error('스켈레톤 생성 중 오류 발생:', e)
|
|
||||||
if (canvas.skeletonStates) {
|
|
||||||
canvas.skeletonStates[roofId] = false
|
|
||||||
canvas.skeletonStates = {}
|
|
||||||
canvas.skeletonLines = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user