dev #549
@ -222,6 +222,7 @@ export const SAVE_KEY = [
|
||||
'skeletonLines',
|
||||
'skeleton',
|
||||
'viewportTransform',
|
||||
'outerLineFix',
|
||||
'adjustRoofLines',
|
||||
]
|
||||
|
||||
|
||||
@ -122,6 +122,21 @@ export default function PassivityCircuitAllocation(props) {
|
||||
return
|
||||
}
|
||||
|
||||
// targetModule중 북면 설치 여부가 Y인 것과 N인 것이 혼합이면 안됨.
|
||||
const targetModuleGroup = [...new Set(canvas
|
||||
.getObjects()
|
||||
.filter((obj) => obj.name === POLYGON_TYPE.MODULE && targetModules.includes(obj.id))
|
||||
.map((obj) => obj.moduleInfo.northModuleYn))]
|
||||
|
||||
if (targetModuleGroup.length > 1) {
|
||||
swalFire({
|
||||
text: getMessage('module.circuit.fix.not.same.roof.error'),
|
||||
type: 'alert',
|
||||
icon: 'warning',
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
switch (pcsTpCd) {
|
||||
case 'INDFCS': {
|
||||
const originHaveThisPcsModules = canvas
|
||||
|
||||
@ -142,6 +142,15 @@ export function useMovementSetting(id) {
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
const roofs = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||
if (roofs.length === 0) {
|
||||
swalFire({ text: getMessage('roof.line.not.found') })
|
||||
closePopup(id)
|
||||
return
|
||||
}
|
||||
}, [])
|
||||
|
||||
/** object 선택이 변경될 때 처리*/
|
||||
useEffect(() => {
|
||||
if (FOLLOW_LINE_REF.current != null) {
|
||||
@ -186,7 +195,6 @@ export function useMovementSetting(id) {
|
||||
canvas.renderAll()
|
||||
}, [currentObject])
|
||||
|
||||
|
||||
const clearRef = () => {
|
||||
if (type === TYPE.FLOW_LINE) {
|
||||
// 안전한 ref 접근
|
||||
@ -258,23 +266,25 @@ export function useMovementSetting(id) {
|
||||
let value = ''
|
||||
let direction = ''
|
||||
|
||||
if (Math.abs(target.y1 - target.y2) < 0.5) { // 수평 라인
|
||||
if (Math.abs(target.y1 - target.y2) < 0.5) {
|
||||
// 수평 라인
|
||||
value = Big(targetTop).minus(currentY).times(10).round(0)
|
||||
|
||||
// 방향 감지
|
||||
if (value.toNumber() > 0) {
|
||||
direction = 'up' // 마우스가 라인 위쪽에 있음 (위로 움직임)
|
||||
direction = 'up' // 마우스가 라인 위쪽에 있음 (위로 움직임)
|
||||
} else if (value.toNumber() < 0) {
|
||||
direction = 'down' // 마우스가 라인 아래쪽에 있음 (아래로 움직임)
|
||||
direction = 'down' // 마우스가 라인 아래쪽에 있음 (아래로 움직임)
|
||||
}
|
||||
} else { // 수직 라인
|
||||
} else {
|
||||
// 수직 라인
|
||||
value = Big(targetLeft).minus(currentX).times(10).round(0).neg()
|
||||
|
||||
// 방향 감지
|
||||
if (value.toNumber() > 0) {
|
||||
direction = 'right' // 마우스가 라인 오른쪽에 있음 (오른쪽으로 움직임)
|
||||
direction = 'right' // 마우스가 라인 오른쪽에 있음 (오른쪽으로 움직임)
|
||||
} else if (value.toNumber() < 0) {
|
||||
direction = 'left' // 마우스가 라인 왼쪽에 있음 (왼쪽으로 움직임)
|
||||
direction = 'left' // 마우스가 라인 왼쪽에 있음 (왼쪽으로 움직임)
|
||||
}
|
||||
}
|
||||
|
||||
@ -312,37 +322,35 @@ export function useMovementSetting(id) {
|
||||
const midY = Big(target.y1).plus(target.y2).div(2)
|
||||
const wall = canvas.getObjects().find((obj) => obj.id === target.attributes.wallId)
|
||||
|
||||
|
||||
|
||||
const result = getSelectLinePosition(wall, target, {
|
||||
testDistance: 5, // 테스트 거리
|
||||
debug: true // 디버깅 로그 출력
|
||||
});
|
||||
testDistance: 5, // 테스트 거리
|
||||
debug: true, // 디버깅 로그 출력
|
||||
})
|
||||
//console.log("1111litarget:::::", target);
|
||||
//console.log("1111linePosition:::::", result.position); // 'top', 'bottom', 'left', 'right'
|
||||
|
||||
let linePosition = result.position;
|
||||
//console.log("1111linePosition:::::", direction, linePosition);
|
||||
let linePosition = result.position
|
||||
//console.log("1111linePosition:::::", direction, linePosition);
|
||||
|
||||
if (target.y1 === target.y2) { //수평벽
|
||||
if (target.y1 === target.y2) {
|
||||
//수평벽
|
||||
|
||||
const setRadioStates = (isUp) => {
|
||||
if (UP_DOWN_REF.UP_RADIO_REF.current) {
|
||||
UP_DOWN_REF.UP_RADIO_REF.current.checked = isUp;
|
||||
UP_DOWN_REF.UP_RADIO_REF.current.checked = isUp
|
||||
}
|
||||
if (UP_DOWN_REF.DOWN_RADIO_REF.current) {
|
||||
UP_DOWN_REF.DOWN_RADIO_REF.current.checked = !isUp;
|
||||
UP_DOWN_REF.DOWN_RADIO_REF.current.checked = !isUp
|
||||
}
|
||||
};
|
||||
|
||||
if (linePosition === 'top') {
|
||||
setRadioStates(value.s !== -1);
|
||||
} else if (linePosition === 'bottom') {
|
||||
setRadioStates(value.s !== 1);
|
||||
}
|
||||
|
||||
if(direction === 'up') {
|
||||
if (linePosition === 'top') {
|
||||
setRadioStates(value.s !== -1)
|
||||
} else if (linePosition === 'bottom') {
|
||||
setRadioStates(value.s !== 1)
|
||||
}
|
||||
|
||||
if (direction === 'up') {
|
||||
}
|
||||
/*
|
||||
checkPoint = { x: midX.toNumber(), y: midY.plus(10).toNumber() }
|
||||
@ -367,20 +375,19 @@ export function useMovementSetting(id) {
|
||||
}
|
||||
*/
|
||||
} else {
|
||||
|
||||
const setRadioStates = (isUp) => {
|
||||
if (UP_DOWN_REF.UP_RADIO_REF.current) {
|
||||
UP_DOWN_REF.UP_RADIO_REF.current.checked = isUp;
|
||||
UP_DOWN_REF.UP_RADIO_REF.current.checked = isUp
|
||||
}
|
||||
if (UP_DOWN_REF.DOWN_RADIO_REF.current) {
|
||||
UP_DOWN_REF.DOWN_RADIO_REF.current.checked = !isUp;
|
||||
UP_DOWN_REF.DOWN_RADIO_REF.current.checked = !isUp
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (linePosition === 'left') {
|
||||
setRadioStates(value.s !== 1);
|
||||
setRadioStates(value.s !== 1)
|
||||
} else if (linePosition === 'right') {
|
||||
setRadioStates(value.s !== -1);
|
||||
setRadioStates(value.s !== -1)
|
||||
}
|
||||
/*
|
||||
checkPoint = { x: midX.plus(10).toNumber(), y: midY.toNumber() }
|
||||
@ -407,11 +414,8 @@ export function useMovementSetting(id) {
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
const mouseDownEvent = (e) => {
|
||||
canvas
|
||||
.getObjects()
|
||||
@ -460,7 +464,6 @@ export function useMovementSetting(id) {
|
||||
canvas.renderAll()
|
||||
}
|
||||
|
||||
|
||||
const target = selectedObject.current !== null ? selectedObject.current : CONFIRM_LINE_REF.current?.target
|
||||
if (!target) return
|
||||
|
||||
@ -468,23 +471,23 @@ export function useMovementSetting(id) {
|
||||
const roof = canvas.getObjects().find((obj) => obj.id === roofId)
|
||||
|
||||
// 현이동, 동이동 추가
|
||||
let flPointValue = FLOW_LINE_REF.POINTER_INPUT_REF.current?.value ?? 0;
|
||||
let flFilledValue = FLOW_LINE_REF.FILLED_INPUT_REF.current?.value ?? 0;
|
||||
flPointValue = (flFilledValue > 0 || flFilledValue < 0) ? flFilledValue : flPointValue;
|
||||
let flPointValue = FLOW_LINE_REF.POINTER_INPUT_REF.current?.value ?? 0
|
||||
let flFilledValue = FLOW_LINE_REF.FILLED_INPUT_REF.current?.value ?? 0
|
||||
flPointValue = flFilledValue > 0 || flFilledValue < 0 ? flFilledValue : flPointValue
|
||||
const moveFlowLine = typeRef.current === TYPE.FLOW_LINE ? flPointValue : 0
|
||||
|
||||
let udPointValue = UP_DOWN_REF.POINTER_INPUT_REF.current?.value ?? 0;
|
||||
let udFilledValue = UP_DOWN_REF.FILLED_INPUT_REF.current?.value ?? 0;
|
||||
udPointValue = udFilledValue > 0 ? udFilledValue : udPointValue;
|
||||
let udPointValue = UP_DOWN_REF.POINTER_INPUT_REF.current?.value ?? 0
|
||||
let udFilledValue = UP_DOWN_REF.FILLED_INPUT_REF.current?.value ?? 0
|
||||
udPointValue = udFilledValue > 0 ? udFilledValue : udPointValue
|
||||
const moveUpDown = typeRef.current === TYPE.UP_DOWN ? udPointValue : 0
|
||||
roof.moveFlowLine = parseInt(moveFlowLine, 10) || 0;
|
||||
roof.moveUpDown = parseInt(moveUpDown, 10) || 0;
|
||||
roof.moveDirect = "";
|
||||
roof.moveFlowLine = parseInt(moveFlowLine, 10) || 0
|
||||
roof.moveUpDown = parseInt(moveUpDown, 10) || 0
|
||||
roof.moveDirect = ''
|
||||
roof.moveSelectLine = target
|
||||
//console.log("target::::", target, roof.moveSelectLine)
|
||||
const wall = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.WALL && obj.attributes.roofId === roofId)
|
||||
const baseLines = wall.baseLines
|
||||
let centerPoint = wall.getCenterPoint();
|
||||
let centerPoint = wall.getCenterPoint()
|
||||
let targetBaseLines = []
|
||||
let isGableRoof
|
||||
if (typeRef.current === TYPE.FLOW_LINE) {
|
||||
@ -522,9 +525,19 @@ export function useMovementSetting(id) {
|
||||
return minX <= line.x1 && line.x1 <= maxX && minX <= line.x2 && line.x2 <= maxX
|
||||
})
|
||||
if (isGableRoof && currentBaseLines.length > 0) {
|
||||
currentBaseLines.forEach((line) => targetBaseLines.push({ line, distance: Big(line.y1).minus(target.y1).abs().toNumber() }))
|
||||
currentBaseLines.forEach((line) =>
|
||||
targetBaseLines.push({
|
||||
line,
|
||||
distance: Big(line.y1).minus(target.y1).abs().toNumber(),
|
||||
}),
|
||||
)
|
||||
} else {
|
||||
checkBaseLines.forEach((line) => targetBaseLines.push({ line, distance: Big(target.y1).minus(line.y1).abs().toNumber() }))
|
||||
checkBaseLines.forEach((line) =>
|
||||
targetBaseLines.push({
|
||||
line,
|
||||
distance: Big(target.y1).minus(line.y1).abs().toNumber(),
|
||||
}),
|
||||
)
|
||||
}
|
||||
baseLines
|
||||
.filter((line) => line.y1 === line.y2 && line.y1 < target.y1)
|
||||
@ -538,9 +551,19 @@ export function useMovementSetting(id) {
|
||||
return minX <= line.x1 && line.x1 <= maxX && minX <= line.x2 && line.x2 <= maxX
|
||||
})
|
||||
if (isGableRoof && currentBaseLines.length > 0) {
|
||||
currentBaseLines.forEach((line) => targetBaseLines.push({ line, distance: Big(line.y1).minus(target.y1).abs().toNumber() }))
|
||||
currentBaseLines.forEach((line) =>
|
||||
targetBaseLines.push({
|
||||
line,
|
||||
distance: Big(line.y1).minus(target.y1).abs().toNumber(),
|
||||
}),
|
||||
)
|
||||
} else {
|
||||
checkBaseLines.forEach((line) => targetBaseLines.push({ line, distance: Big(line.y1).minus(target.y1).abs().toNumber() }))
|
||||
checkBaseLines.forEach((line) =>
|
||||
targetBaseLines.push({
|
||||
line,
|
||||
distance: Big(line.y1).minus(target.y1).abs().toNumber(),
|
||||
}),
|
||||
)
|
||||
}
|
||||
break
|
||||
case 'right':
|
||||
@ -551,9 +574,19 @@ export function useMovementSetting(id) {
|
||||
return minY <= line.y1 && line.y1 <= maxY && minY <= line.y2 && line.y2 <= maxY
|
||||
})
|
||||
if (isGableRoof && currentBaseLines.length > 0) {
|
||||
currentBaseLines.forEach((line) => targetBaseLines.push({ line, distance: Big(line.x1).minus(target.x1).abs().toNumber() }))
|
||||
currentBaseLines.forEach((line) =>
|
||||
targetBaseLines.push({
|
||||
line,
|
||||
distance: Big(line.x1).minus(target.x1).abs().toNumber(),
|
||||
}),
|
||||
)
|
||||
} else {
|
||||
checkBaseLines.forEach((line) => targetBaseLines.push({ line, distance: Big(target.x1).minus(line.x1).abs().toNumber() }))
|
||||
checkBaseLines.forEach((line) =>
|
||||
targetBaseLines.push({
|
||||
line,
|
||||
distance: Big(target.x1).minus(line.x1).abs().toNumber(),
|
||||
}),
|
||||
)
|
||||
}
|
||||
break
|
||||
case 'left':
|
||||
@ -564,9 +597,19 @@ export function useMovementSetting(id) {
|
||||
return minY <= line.y1 && line.y1 <= maxY && minY <= line.y2 && line.y2 <= maxY
|
||||
})
|
||||
if (isGableRoof && currentBaseLines.length > 0) {
|
||||
currentBaseLines.forEach((line) => targetBaseLines.push({ line, distance: Big(line.x1).minus(target.x1).abs().toNumber() }))
|
||||
currentBaseLines.forEach((line) =>
|
||||
targetBaseLines.push({
|
||||
line,
|
||||
distance: Big(line.x1).minus(target.x1).abs().toNumber(),
|
||||
}),
|
||||
)
|
||||
} else {
|
||||
checkBaseLines.forEach((line) => targetBaseLines.push({ line, distance: Big(target.x1).minus(line.x1).abs().toNumber() }))
|
||||
checkBaseLines.forEach((line) =>
|
||||
targetBaseLines.push({
|
||||
line,
|
||||
distance: Big(target.x1).minus(line.x1).abs().toNumber(),
|
||||
}),
|
||||
)
|
||||
}
|
||||
break
|
||||
}
|
||||
@ -576,18 +619,18 @@ export function useMovementSetting(id) {
|
||||
}
|
||||
|
||||
// Remove duplicate lines
|
||||
const uniqueLines = new Map();
|
||||
targetBaseLines = targetBaseLines.filter(item => {
|
||||
const key = `${item.line.x1},${item.line.y1},${item.line.x2},${item.line.y2}`;
|
||||
const uniqueLines = new Map()
|
||||
targetBaseLines = targetBaseLines.filter((item) => {
|
||||
const key = `${item.line.x1},${item.line.y1},${item.line.x2},${item.line.y2}`
|
||||
if (!uniqueLines.has(key)) {
|
||||
uniqueLines.set(key, true);
|
||||
return true;
|
||||
uniqueLines.set(key, true)
|
||||
return true
|
||||
}
|
||||
return false;
|
||||
});
|
||||
return false
|
||||
})
|
||||
|
||||
// Sort by distance
|
||||
targetBaseLines.sort((a, b) => a.distance - b.distance);
|
||||
targetBaseLines.sort((a, b) => a.distance - b.distance)
|
||||
targetBaseLines = targetBaseLines.filter((line) => line.distance === targetBaseLines[0].distance)
|
||||
|
||||
if (isGableRoof) {
|
||||
@ -621,27 +664,22 @@ export function useMovementSetting(id) {
|
||||
let value
|
||||
if (typeRef.current === TYPE.FLOW_LINE) {
|
||||
value = (() => {
|
||||
const filledValue = FLOW_LINE_REF.FILLED_INPUT_REF.current?.value;
|
||||
const pointerValue = FLOW_LINE_REF.POINTER_INPUT_REF.current?.value;
|
||||
const filledValue = FLOW_LINE_REF.FILLED_INPUT_REF.current?.value
|
||||
const pointerValue = FLOW_LINE_REF.POINTER_INPUT_REF.current?.value
|
||||
|
||||
if (filledValue && !isNaN(filledValue) && filledValue.trim() !== '') {
|
||||
return Big(filledValue).times(2);
|
||||
return Big(filledValue).times(2)
|
||||
} else if (pointerValue && !isNaN(pointerValue) && pointerValue.trim() !== '') {
|
||||
return Big(pointerValue).times(2);
|
||||
return Big(pointerValue).times(2)
|
||||
}
|
||||
return Big(0); // 기본값으로 0 반환 또는 다른 적절한 기본값
|
||||
})();
|
||||
return Big(0) // 기본값으로 0 반환 또는 다른 적절한 기본값
|
||||
})()
|
||||
if (Math.abs(target.y1 - target.y2) < 0.5) {
|
||||
value = value.neg()
|
||||
}
|
||||
} else {
|
||||
console.log("error::", UP_DOWN_REF.POINTER_INPUT_REF.current.value)
|
||||
value = Big(
|
||||
(UP_DOWN_REF?.FILLED_INPUT_REF?.current?.value?.trim() ||
|
||||
UP_DOWN_REF?.POINTER_INPUT_REF?.current?.value?.trim() ||
|
||||
'0'
|
||||
)
|
||||
);
|
||||
console.log('error::', UP_DOWN_REF.POINTER_INPUT_REF.current.value)
|
||||
value = Big(UP_DOWN_REF?.FILLED_INPUT_REF?.current?.value?.trim() || UP_DOWN_REF?.POINTER_INPUT_REF?.current?.value?.trim() || '0')
|
||||
|
||||
const midX = Big(target.x1).plus(target.x2).div(2)
|
||||
const midY = Big(target.y1).plus(target.y2).div(2)
|
||||
@ -665,17 +703,16 @@ export function useMovementSetting(id) {
|
||||
// console.log("2222저장된 moveSelectLine:", roof.moveSelectLine);
|
||||
// console.log("222wall::::", wall.points)
|
||||
const result = getSelectLinePosition(wall, target, {
|
||||
testDistance: 5, // 테스트 거리
|
||||
debug: true // 디버깅 로그 출력
|
||||
});
|
||||
testDistance: 5, // 테스트 거리
|
||||
debug: true, // 디버깅 로그 출력
|
||||
})
|
||||
|
||||
//console.log("2222linePosition:::::", result.position);
|
||||
//console.log("222moveDirect:::::", roof.moveDirect);
|
||||
|
||||
// 디버깅용 분류 결과 확인
|
||||
|
||||
// 디버깅용 분류 결과 확인
|
||||
|
||||
let linePosition = result.position;
|
||||
let linePosition = result.position
|
||||
roof.movePosition = linePosition
|
||||
value = value.div(10)
|
||||
targetBaseLines
|
||||
@ -684,15 +721,14 @@ export function useMovementSetting(id) {
|
||||
const currentLine = target.line
|
||||
|
||||
//console.log("linePosition::::::::::::::", linePosition)
|
||||
if (UP_DOWN_REF?.DOWN_RADIO_REF?.current?.checked ){
|
||||
if (UP_DOWN_REF?.DOWN_RADIO_REF?.current?.checked) {
|
||||
//position확인
|
||||
if(linePosition === 'bottom' || linePosition === 'right') {
|
||||
if (linePosition === 'bottom' || linePosition === 'right') {
|
||||
//console.log("1value::::::::::::::", value.toString())
|
||||
value = value.neg()
|
||||
|
||||
}
|
||||
}else {
|
||||
if(linePosition === 'top' || linePosition === 'left') {
|
||||
} else {
|
||||
if (linePosition === 'top' || linePosition === 'left') {
|
||||
//console.log("1value::::::::::::::", value.toString())
|
||||
value = value.neg()
|
||||
}
|
||||
@ -753,7 +789,6 @@ export function useMovementSetting(id) {
|
||||
|
||||
// javascript
|
||||
|
||||
|
||||
return {
|
||||
TYPE,
|
||||
closePopup,
|
||||
@ -765,4 +800,3 @@ export function useMovementSetting(id) {
|
||||
handleSave,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -251,6 +251,7 @@ export function useOuterLineWall(id, propertiesId) {
|
||||
removeAllDocumentEventListeners()
|
||||
canvas?.renderAll()
|
||||
setOuterLineFix(true)
|
||||
canvas.outerLineFix = true
|
||||
closePopup(id)
|
||||
ccwCheck()
|
||||
addPopup(propertiesId, 1, <RoofShapeSetting id={propertiesId} pos={{ x: 50, y: 230 }} />)
|
||||
|
||||
@ -471,19 +471,57 @@ export function useRoofAllocationSetting(id) {
|
||||
const existingEaveLineIds = new Set(roofBase.lines.map((line) => line.id))
|
||||
const newEaveLines = roofEaveHelpLines.filter((line) => !existingEaveLineIds.has(line.id))
|
||||
// Filter out lines from roofBase.lines that share any points with newEaveLines
|
||||
const linesToKeep = roofBase.lines.filter((roofLine) => {
|
||||
return !newEaveLines.some((eaveLine) => {
|
||||
// Check if any endpoint of roofLine matches any endpoint of eaveLine
|
||||
return (
|
||||
// Check if any endpoint of roofLine matches any endpoint of eaveLine
|
||||
(Math.abs(roofLine.x1 - eaveLine.x1) < 0.1 && Math.abs(roofLine.y1 - eaveLine.y1) < 0.1) || // p1 matches p1
|
||||
(Math.abs(roofLine.x2 - eaveLine.x2) < 0.1 && Math.abs(roofLine.y2 - eaveLine.y2) < 0.1) // p2 matches p2
|
||||
)
|
||||
})
|
||||
})
|
||||
const linesToKeep = roofBase.lines.filter(roofLine => {
|
||||
const shouldRemove = newEaveLines.some(eaveLine => {
|
||||
// 1. 기본적인 포인트 일치 확인
|
||||
const rX1 = roofLine.x1, rY1 = roofLine.y1, rX2 = roofLine.x2, rY2 = roofLine.y2;
|
||||
const eX1 = eaveLine.x1, eY1 = eaveLine.y1, eX2 = eaveLine.x2, eY2 = eaveLine.y2;
|
||||
|
||||
// Combine remaining lines with newEaveLines
|
||||
roofBase.lines = [...linesToKeep, ...newEaveLines]
|
||||
const isP1Matched = (Math.abs(rX1 - eX1) < 0.1 && Math.abs(rY1 - eY1) < 0.1) || (Math.abs(rX1 - eX2) < 0.1 && Math.abs(rY1 - eY2) < 0.1);
|
||||
const isP2Matched = (Math.abs(rX2 - eX1) < 0.1 && Math.abs(rY2 - eY1) < 0.1) || (Math.abs(rX2 - eX2) < 0.1 && Math.abs(rY2 - eY2) < 0.1);
|
||||
|
||||
if (isP1Matched || isP2Matched) {
|
||||
// 2. 일직선(평행)인지 확인
|
||||
const dx1 = rX2 - rX1;
|
||||
const dy1 = rY2 - rY1;
|
||||
const dx2 = eX2 - eX1;
|
||||
const dy2 = eY2 - eY1;
|
||||
const crossProduct = Math.abs(dx1 * dy2 - dy1 * dx2);
|
||||
const mag1 = Math.sqrt(dx1 * dx1 + dy1 * dy1);
|
||||
const mag2 = Math.sqrt(dx2 * dx2 + dy2 * dy2);
|
||||
const isStraight = (mag1 * mag2) === 0 ? true : (crossProduct / (mag1 * mag2) < 0.01);
|
||||
|
||||
if (isStraight) {
|
||||
// 3. [핵심] 몸통이 포개지는지(Overlap) 확인
|
||||
// 한 선의 끝점이 다른 선의 "내부"에 들어와 있는지 체크
|
||||
const isPointInside = (x, y, x1, y1, x2, y2) => {
|
||||
const dotProduct = (x - x1) * (x2 - x1) + (y - y1) * (y2 - y1);
|
||||
if (dotProduct < 0.1) return false; // 시작점 바깥쪽
|
||||
const squaredLength = (x2 - x1) ** 2 + (y2 - y1) ** 2;
|
||||
if (dotProduct > squaredLength - 0.1) return false; // 끝점 바깥쪽
|
||||
return true; // 선의 내부(몸통)에 있음
|
||||
};
|
||||
|
||||
// roofLine의 끝점 중 하나가 eaveLine의 몸통 안에 있거나,
|
||||
// eaveLine의 끝점 중 하나가 roofLine의 몸통 안에 있으면 "포개짐"으로 판단
|
||||
const isOverlapping =
|
||||
isPointInside(rX1, rY1, eX1, eY1, eX2, eY2) ||
|
||||
isPointInside(rX2, rY2, eX1, eY1, eX2, eY2) ||
|
||||
isPointInside(eX1, eY1, rX1, rY1, rX2, rY2) ||
|
||||
isPointInside(eX2, eY2, rX1, rY1, rX2, rY2);
|
||||
|
||||
if (isOverlapping) {
|
||||
console.log('Removing overlapping line:', roofLine);
|
||||
return true; // 포개지는 경우에만 삭제
|
||||
}
|
||||
}
|
||||
}
|
||||
return false; // 끝점만 닿아 있거나 직각인 경우는 살림
|
||||
});
|
||||
return !shouldRemove;
|
||||
});
|
||||
// Combine remaining lines with newEaveLines
|
||||
roofBase.lines = [...linesToKeep, ...newEaveLines];
|
||||
} else {
|
||||
roofBase.lines = [...roofEaveHelpLines]
|
||||
}
|
||||
|
||||
@ -7,7 +7,6 @@ import { useEvent } from '@/hooks/useEvent'
|
||||
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
|
||||
import { useMode } from '@/hooks/useMode'
|
||||
import { usePolygon } from '@/hooks/usePolygon'
|
||||
import { outerLineFixState } from '@/store/outerLineAtom'
|
||||
import { useSwal } from '@/hooks/useSwal'
|
||||
import { usePopup } from '@/hooks/usePopup'
|
||||
import { getChonByDegree } from '@/util/canvas-util'
|
||||
@ -46,11 +45,9 @@ export function useRoofShapePassivitySetting(id) {
|
||||
{ id: 3, name: getMessage('windage'), type: TYPES.SHED },
|
||||
]
|
||||
|
||||
const outerLineFix = useRecoilValue(outerLineFixState)
|
||||
|
||||
useEffect(() => {
|
||||
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||
if (!outerLineFix || outerLines.length === 0) {
|
||||
if (!canvas.outerLineFix || outerLines.length === 0) {
|
||||
swalFire({ text: getMessage('wall.line.not.found') })
|
||||
closePopup(id)
|
||||
return
|
||||
|
||||
@ -81,6 +81,12 @@ export function useRoofShapeSetting(id) {
|
||||
}, [jerkinHeadPitch])
|
||||
|
||||
useEffect(() => {
|
||||
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||
if (!canvas.outerLineFix || outerLines.length === 0) {
|
||||
swalFire({ text: getMessage('wall.line.not.found') })
|
||||
closePopup(id)
|
||||
return
|
||||
}
|
||||
return () => {
|
||||
if (!isFixRef.current) {
|
||||
return
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import { useRecoilValue, useResetRecoilState } from 'recoil'
|
||||
import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil'
|
||||
import {
|
||||
canvasSettingState,
|
||||
canvasState,
|
||||
@ -50,7 +50,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
|
||||
const { changeCorridorDimensionText } = useText()
|
||||
const currentCanvasPlan = useRecoilValue(currentCanvasPlanState)
|
||||
const { fetchSettings } = useCanvasSetting(false)
|
||||
const currentObject = useRecoilValue(currentObjectState)
|
||||
const [currentObject, setCurrentObject] = useRecoilState(currentObjectState)
|
||||
const [popupId, setPopupId] = useState(uuidv4())
|
||||
|
||||
const applySurfaceShape = (surfaceRefs, selectedType, id) => {
|
||||
@ -755,6 +755,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
|
||||
type: 'confirm',
|
||||
confirmFn: () => {
|
||||
canvas.clear()
|
||||
delete canvas.outerLineFix
|
||||
|
||||
if (backgroundImage) {
|
||||
fabric.Image.fromURL(`${backgroundImage.path}`, function (img) {
|
||||
@ -1524,6 +1525,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
|
||||
// 개별 객체들을 다시 캔버스에 추가하고 처리
|
||||
group.getObjects().forEach((obj) => {
|
||||
canvas.add(obj)
|
||||
obj.dirty = true // 캐시 무효화
|
||||
obj.setCoords()
|
||||
|
||||
// currentObject인 경우 추가 처리
|
||||
@ -1534,6 +1536,8 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
|
||||
// QPolygon 내부 구조 재구성 (선이 깨지는 문제 해결)
|
||||
if (obj.type === 'QPolygon' && obj.lines) {
|
||||
obj.initLines()
|
||||
obj.dirty = true
|
||||
obj.setCoords()
|
||||
}
|
||||
|
||||
obj.set({
|
||||
@ -1544,6 +1548,8 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
|
||||
// relatedObject인 경우에도 필요한 처리
|
||||
if (obj.type === 'QPolygon' && obj.lines) {
|
||||
obj.initLines()
|
||||
obj.dirty = true
|
||||
obj.setCoords()
|
||||
}
|
||||
if (obj.type === 'group') {
|
||||
// 회전 후의 points를 groupPoints로 업데이트
|
||||
@ -1551,24 +1557,30 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
|
||||
|
||||
obj.recalculateGroupPoints()
|
||||
|
||||
obj._objects?.forEach((obj) => {
|
||||
obj.initLines()
|
||||
obj.fire('modified')
|
||||
obj._objects?.forEach((innerObj) => {
|
||||
innerObj.initLines()
|
||||
innerObj.dirty = true
|
||||
innerObj.setCoords()
|
||||
innerObj.fire('modified')
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
currentObject.dirty = true
|
||||
currentObject.setCoords()
|
||||
currentObject.fire('modified')
|
||||
currentObject.fire('polygonMoved')
|
||||
// 화살표와 선 다시 그리기
|
||||
drawDirectionArrow(currentObject)
|
||||
setTimeout(() => {
|
||||
setPolygonLinesActualSize(currentObject)
|
||||
changeSurfaceLineType(currentObject)
|
||||
currentObject.dirty = true
|
||||
currentObject.setCoords()
|
||||
canvas.requestRenderAll()
|
||||
setCurrentObject(currentObject)
|
||||
}, 500)
|
||||
|
||||
// currentObject를 다시 선택 상태로 설정
|
||||
canvas.setActiveObject(currentObject)
|
||||
canvas.renderAll()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user