skeleton-utils
This commit is contained in:
parent
7d9b6d5225
commit
99c7759e00
@ -4,8 +4,8 @@
|
||||
*/
|
||||
|
||||
import SkeletonBuilder from '@/lib/skeletons/SkeletonBuilder';
|
||||
import { fabric } from 'fabric';
|
||||
import { LINE_TYPE } from '@/common/common';
|
||||
import { fabric } from 'fabric'
|
||||
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
|
||||
import { QLine } from '@/components/fabric/QLine';
|
||||
import { calcLinePlaneSize } from '@/util/qpolygon-utils';
|
||||
|
||||
@ -93,11 +93,14 @@ const extractUniqueLinesFromEdges = (skeletonEdges) => {
|
||||
export const drawSkeletonRidgeRoof = (roofId, canvas, textMode) => {
|
||||
try {
|
||||
const roof = canvas?.getObjects().find((object) => object.id === roofId);
|
||||
const wall = canvas.getObjects().find((object) => object.name === POLYGON_TYPE.WALL && object.attributes.roofId === roofId)
|
||||
|
||||
if (!roof) {
|
||||
console.error(`Roof with id "${roofId}" not found.`);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 1. 기존 스켈레톤 라인 제거
|
||||
const existingSkeletonLines = canvas.getObjects().filter(obj =>
|
||||
obj.parentId === roofId && obj.attributes?.type === 'skeleton'
|
||||
@ -111,6 +114,11 @@ export const drawSkeletonRidgeRoof = (roofId, canvas, textMode) => {
|
||||
return;
|
||||
}
|
||||
|
||||
/** 외벽선 */
|
||||
const baseLines = wall.baseLines.filter((line) => line.attributes.planeSize > 0)
|
||||
const baseLinePoints = baseLines.map((line) => ({ x: line.x1, y: line.y1 }))
|
||||
|
||||
|
||||
// 3. 스켈레톤 생성
|
||||
const multiPolygon = [[coordinates]]; // GeoJSON MultiPolygon 형식
|
||||
const skeleton = SkeletonBuilder.BuildFromGeoJSON(multiPolygon);
|
||||
@ -127,15 +135,65 @@ export const drawSkeletonRidgeRoof = (roofId, canvas, textMode) => {
|
||||
const skeletonLines = [];
|
||||
const outerLines = pointsToLines(coordinates);
|
||||
|
||||
for (const baseLine of baseLines) {
|
||||
const { type } = baseLine.get("attributes");
|
||||
|
||||
if(type === LINE_TYPE.WALLLINE.EAVES) {
|
||||
|
||||
|
||||
|
||||
}else if(type === LINE_TYPE.WALLLINE.RIDGE) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
linesToDraw.forEach((line, index) => {
|
||||
// 외곽선과 겹치는 스켈레톤 라인은 그리지 않음
|
||||
const isOverlapping = outerLines.some(outerLine => linesOverlap(line, outerLine));
|
||||
if (isOverlapping) {
|
||||
// Array.find()를 사용하여 baseLines 배열에서 일치하는 라인을 찾습니다.
|
||||
const foundBaseLine = baseLines.filter(baseLine => {
|
||||
// baseLine (fabric.QLine)에서 좌표를 추출합니다.
|
||||
const { p1: baseP1, p2: baseP2 } = getPointsFromQLine(baseLine);
|
||||
|
||||
const attributes = baseLine.get('attributes');
|
||||
|
||||
// 2. 속성 객체에서 type 값을 추출합니다.
|
||||
const type = attributes.type;
|
||||
|
||||
// 이제 'type' 변수를 조건문 등에서 사용할 수 있습니다.
|
||||
console.log('라인 타입:', type);
|
||||
|
||||
// lineToDraw의 좌표 (p1, p2)와 baseLine의 좌표를 비교합니다.
|
||||
// 라인 방향이 다를 수 있으므로 정방향과 역방향 모두 확인합니다.
|
||||
|
||||
// 정방향 일치: (p1 -> p2) == (baseP1 -> baseP2)
|
||||
const forwardMatch =
|
||||
line.x1 === baseP1.x && line.y1 === baseP1.y &&
|
||||
line.x2 === baseP2.x && line.y2 === baseP2.y;
|
||||
|
||||
// 역방향 일치: (p1 -> p2) == (baseP2 -> baseP1)
|
||||
const reverseMatch =
|
||||
line.x1 === baseP2.x && line.y1 === baseP2.y &&
|
||||
line.x2 === baseP1.x && line.y2 === baseP1.y;
|
||||
|
||||
return forwardMatch || reverseMatch;
|
||||
});
|
||||
|
||||
// 일치하는 라인을 찾았는지 확인
|
||||
if (foundBaseLine) {
|
||||
console.log(`linesToDraw[${index}]와 일치하는 라인을 찾았습니다:`, foundBaseLine);
|
||||
// 여기서 foundBaseLine을 사용하여 필요한 작업을 수행할 수 있습니다.
|
||||
} else {
|
||||
|
||||
console.log(`linesToDraw[${index}]에 대한 일치하는 라인을 찾지 못했습니다.`);
|
||||
}
|
||||
console.log(`Skeleton line (edge ${line.edgeIndex}) is overlapping with a baseLine. It will not be drawn.`);
|
||||
return;
|
||||
}
|
||||
|
||||
const isDiagonal = Math.abs(line.x1 - line.x2) > 1e-6 && Math.abs(line.y1 - line.y2) > 1e-6;
|
||||
const isEaves = baseLinePoints.some(point => linesOverlap(line, point));
|
||||
|
||||
const skeletonLine = new QLine([line.x1, line.y1, line.x2, line.y2], {
|
||||
parentId: roofId,
|
||||
@ -147,7 +205,7 @@ export const drawSkeletonRidgeRoof = (roofId, canvas, textMode) => {
|
||||
textMode: textMode,
|
||||
attributes: {
|
||||
roofId: roofId,
|
||||
type: 'skeleton', // 스켈레톤 타입 식별자
|
||||
type: LINE_TYPE.WALLLINE.EAVES, // 스켈레톤 타입 식별자
|
||||
skeletonIndex: line.edgeIndex,
|
||||
lineIndex: index,
|
||||
planeSize: calcLinePlaneSize(line),
|
||||
@ -160,14 +218,19 @@ export const drawSkeletonRidgeRoof = (roofId, canvas, textMode) => {
|
||||
|
||||
skeletonLines.push(skeletonLine);
|
||||
canvas.add(skeletonLine);
|
||||
|
||||
// 6. roof 객체에 스켈레톤 라인 정보 업데이트
|
||||
roof.innerLines = [...(roof.innerLines || []), ...skeletonLines];
|
||||
skeletonLines.forEach(line => line.bringToFront());
|
||||
|
||||
canvas.renderAll();
|
||||
console.log(`Successfully drew ${linesToDraw.length} unique skeleton lines from ${skeleton.Edges.length} polygons.`);
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
// 6. roof 객체에 스켈레톤 라인 정보 업데이트
|
||||
roof.innerLines = [...(roof.innerLines || []), ...skeletonLines];
|
||||
skeletonLines.forEach(line => line.bringToFront());
|
||||
|
||||
canvas.renderAll();
|
||||
console.log(`Successfully drew ${linesToDraw.length} unique skeleton lines from ${skeleton.Edges.length} polygons.`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('An error occurred while generating the skeleton:', error);
|
||||
@ -227,3 +290,13 @@ function pointsToLines(points) {
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* fabric.QLine에서 시작점과 끝점을 가져옵니다.
|
||||
* @param {fabric.QLine} line
|
||||
* @returns {{p1: {x: number, y: number}, p2: {x: number, y: number}}}
|
||||
*/
|
||||
export const getPointsFromQLine = (line) => {
|
||||
return { p1: { x: line.x1, y: line.y1 }, p2: { x: line.x2, y: line.y2 } };
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user