sortRoofLines 개선

This commit is contained in:
yscha 2025-12-11 00:43:36 +09:00
parent 94fe5889ea
commit c8a04a33fd

View File

@ -318,31 +318,28 @@ const movingLineFromSkeleton = (roofId, canvas) => {
* @param baseLines * @param baseLines
*/ */
export const skeletonBuilder = (roofId, canvas, textMode) => { export const skeletonBuilder = (roofId, canvas, textMode) => {
//처마 //처마
let roof = canvas?.getObjects().find((object) => object.id === roofId) let roof = canvas?.getObjects().find((object) => object.id === roofId)
// [추가] wall 객체를 찾아 roof.lines에 wallId를 직접 주입 (초기화) // [추가] wall 객체를 찾아 roof.lines에 wallId를 직접 주입 (초기화)
// 지붕은 벽을 기반으로 생성되므로 라인의 순서(Index)가 동일합니다. // 지붕은 벽을 기반으로 생성되므로 라인의 순서(Index)가 동일합니다.
const wallObj = canvas.getObjects().find((object) => object.name === POLYGON_TYPE.WALL && object.attributes.roofId === roofId); const wallObj = canvas.getObjects().find((object) => object.name === POLYGON_TYPE.WALL && object.attributes.roofId === roofId)
if (roof && wallObj && roof.lines && wallObj.lines) { if (roof && wallObj && roof.lines && wallObj.lines) {
// 개선된 코드 (기하학적 매칭)
// or use some other unique properties
roof.lines.forEach((rLine, index) => { roof.lines.forEach((rLine, index) => {
// 동일한 인덱스의 벽 라인 가져오기 // 벽 라인 중에서 시작점과 끝점이 일치하는 라인 찾
const wLine = wallObj.lines[index]; const wLine = wallObj.lines[index]
if (wLine) { if (wLine) {
// attributes.wallId는 부모(벽) ID라서 모두 동일합니다. // 안정적인 ID 생성
// 개별 라인을 식별하기 위해 wLine.id (라인 객체 고유 ID)를 저장합니다. rLine.attributes.wallLine = wLine.id; // Use the stable ID
// * 새로고침 시 wLine.id가 바뀌어도, 이 로직이 그때마다 돌면서 최신 ID로 갱신해줍니다.
rLine.attributes.wallLineId = wLine.id;
// 필요하다면 부모 ID도 같이 저장 (참조용) // ...
if (wLine.attributes?.wallId) {
rLine.attributes.parentWallId = wLine.attributes.wallId;
}
} }
})
});
} }
const eavesType = [LINE_TYPE.WALLLINE.EAVES, LINE_TYPE.WALLLINE.HIPANDGABLE] const eavesType = [LINE_TYPE.WALLLINE.EAVES, LINE_TYPE.WALLLINE.HIPANDGABLE]
@ -352,40 +349,35 @@ export const skeletonBuilder = (roofId, canvas, textMode) => {
const wall = canvas.getObjects().find((object) => object.name === POLYGON_TYPE.WALL && object.attributes.roofId === roofId) 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 = wall.baseLines.filter((line) => line.attributes.planeSize > 0)
const baseLines = canvas.getObjects().filter((object) => object.name === 'baseLine' && object.parentId === roofId) || []; const baseLines = canvas.getObjects().filter((object) => object.name === 'baseLine' && object.parentId === roofId) || []
const baseLinePoints = baseLines.map((line) => ({x:line.left, y:line.top})); const baseLinePoints = baseLines.map((line) => ({ x: line.left, y: line.top }))
const outerLines = canvas.getObjects().filter((object) => object.name === 'outerLinePoint') || []; const outerLines = canvas.getObjects().filter((object) => object.name === 'outerLinePoint') || []
const outerLinePoints = outerLines.map((line) => ({x:line.left, y:line.top})) const outerLinePoints = outerLines.map((line) => ({ x: line.left, y: line.top }))
const hipLines = canvas.getObjects().filter((object) => object.name === 'hip' && object.parentId === roofId) || []; 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 ridgeLines = canvas.getObjects().filter((object) => object.name === 'ridge' && object.parentId === roofId) || []
//const skeletonLines = []; //const skeletonLines = [];
// 1. 지붕 폴리곤 좌표 전처리 // 1. 지붕 폴리곤 좌표 전처리
const coordinates = preprocessPolygonCoordinates(roof.points); const coordinates = preprocessPolygonCoordinates(roof.points)
if (coordinates.length < 3) { if (coordinates.length < 3) {
console.warn("Polygon has less than 3 unique points. Cannot generate skeleton."); console.warn('Polygon has less than 3 unique points. Cannot generate skeleton.')
return; return
} }
const moveFlowLine = roof.moveFlowLine || 0; // Provide a default value const moveFlowLine = roof.moveFlowLine || 0 // Provide a default value
const moveUpDown = roof.moveUpDown || 0; // Provide a default value const moveUpDown = roof.moveUpDown || 0 // Provide a default value
let points = roof.points;
let points = roof.points
//마루이동 //마루이동
if (moveFlowLine !== 0 || moveUpDown !== 0) { if (moveFlowLine !== 0 || moveUpDown !== 0) {
points = movingLineFromSkeleton(roofId, canvas) points = movingLineFromSkeleton(roofId, canvas)
} }
console.log('points:', points)
console.log('points:', points);
const geoJSONPolygon = toGeoJSON(points) const geoJSONPolygon = toGeoJSON(points)
try { try {
@ -394,7 +386,7 @@ export const skeletonBuilder = (roofId, canvas, textMode) => {
const skeleton = SkeletonBuilder.BuildFromGeoJSON([[geoJSONPolygon]]) const skeleton = SkeletonBuilder.BuildFromGeoJSON([[geoJSONPolygon]])
// 스켈레톤 데이터를 기반으로 내부선 생성 // 스켈레톤 데이터를 기반으로 내부선 생성
roof.innerLines = roof.innerLines || []; roof.innerLines = roof.innerLines || []
roof.innerLines = createInnerLinesFromSkeleton(roofId, canvas, skeleton, textMode) roof.innerLines = createInnerLinesFromSkeleton(roofId, canvas, skeleton, textMode)
// 캔버스에 스켈레톤 상태 저장 // 캔버스에 스켈레톤 상태 저장
@ -403,12 +395,12 @@ export const skeletonBuilder = (roofId, canvas, textMode) => {
canvas.skeletonLines = [] canvas.skeletonLines = []
} }
canvas.skeletonStates[roofId] = true canvas.skeletonStates[roofId] = true
canvas.skeletonLines = []; canvas.skeletonLines = []
canvas.skeletonLines.push(...roof.innerLines) canvas.skeletonLines.push(...roof.innerLines)
roof.skeletonLines = canvas.skeletonLines; roof.skeletonLines = canvas.skeletonLines
const cleanSkeleton = { const cleanSkeleton = {
Edges: skeleton.Edges.map(edge => ({ Edges: skeleton.Edges.map((edge) => ({
X1: edge.Edge.Begin.X, X1: edge.Edge.Begin.X,
Y1: edge.Edge.Begin.Y, Y1: edge.Edge.Begin.Y,
X2: edge.Edge.End.X, X2: edge.Edge.End.X,
@ -419,15 +411,14 @@ export const skeletonBuilder = (roofId, canvas, textMode) => {
})), })),
roofId: roofId, roofId: roofId,
// Add other necessary top-level properties // Add other necessary top-level properties
}; }
canvas.skeleton = []; canvas.skeleton = []
canvas.skeleton = cleanSkeleton canvas.skeleton = cleanSkeleton
canvas.skeleton.lastPoints = points canvas.skeleton.lastPoints = points
canvas.set("skeleton", cleanSkeleton); canvas.set('skeleton', cleanSkeleton)
canvas.renderAll() canvas.renderAll()
console.log('skeleton rendered.', canvas)
console.log('skeleton rendered.', canvas);
} catch (e) { } catch (e) {
console.error('스켈레톤 생성 중 오류 발생:', e) console.error('스켈레톤 생성 중 오류 발생:', e)
if (canvas.skeletonStates) { if (canvas.skeletonStates) {
@ -798,9 +789,16 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
// const moveLine = sortedWallBaseLines[index] // const moveLine = sortedWallBaseLines[index]
// const wallBaseLine = sortedWallBaseLines[index] // const wallBaseLine = sortedWallBaseLines[index]
console.log("wallLine::::", wallLine) const roofLine = sortRoofLines[index];
const roofLine = sortRoofLines[index]//roofLines.find(line => line.attributes.wallLineId === wallLine.attributes.wallId); if(roofLine.attributes.wallLine !== wallLine.id || (roofLine.idx - 1) !== index ){
console.log("roofLine", roofLine); console.log("wallLine2::::", wallLine.id)
console.log('roofLine:::',roofLine.attributes.wallLine)
console.log("w:::",wallLine.startPoint, wallLine.endPoint)
console.log("R:::",roofLine.startPoint, roofLine.endPoint)
console.log("not matching roofLine", roofLine);
return false
}//roofLines.find(line => line.attributes.wallLineId === wallLine.attributes.wallId);
const currentRoofLine = currentRoofLines[index]; const currentRoofLine = currentRoofLines[index];
const moveLine = sortedBaseLines[index] const moveLine = sortedBaseLines[index]
const wallBaseLine = sortedBaseLines[index] const wallBaseLine = sortedBaseLines[index]