fix(B07): 도각 같은 잠금 도면층을 설계 조작이 집지 않게 한다

잠금 필터가 공용 함수 없이 호출부마다 들어가 있어 넣은 곳은 막히고 안 넣은
곳은 샜다. Ctrl+A는 도각 103개·원지반 16개까지 전부 선택했고, 선택 삭제에는
잠금 검사가 없어 Ctrl+A → Delete 한 번에 도각이 사라졌다. 자르기와 트림·모따기
계열, 커서 강조도 도각을 집었다.

state.ts에 getPickableEntities()(잠금 도면층 제외)를 두고 집기 경로가 그걸
쓴다. 선택은 setSelectedEntityIds() 한 곳에서 막아, 앞으로 생길 선택 경로도
자동으로 잠금 객체를 담지 못한다.

화면맞춤(zoomToFitScreen)도 같은 목록에 맞춘다 — 도각까지 넣으면 A1 한 장
전체가 잡혀 화면의 40%가 여백으로 갔다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-31 14:38:48 +09:00
co-authored by Claude Opus 5
parent fb0b49bf60
commit ee065091c1
5 changed files with 45 additions and 19 deletions
@@ -1,24 +1,30 @@
import type {Point, Polygon} from '@flatten-js/core';
import {assign, createMachine} from 'xstate';
import type {ArcEntity} from '../entities/ArcEntity';
import type {CircleEntity} from '../entities/CircleEntity';
import {EntityName} from '../entities/Entity';
import {LineEntity} from '../entities/LineEntity';
import type {RectangleEntity} from '../entities/RectangleEntity';
import {findClosestEntity} from '../helpers/find-closest-entity';
import {polygonToSegments} from '../helpers/polygon-to-segments';
import type { Point, Polygon } from '@flatten-js/core';
import { assign, createMachine } from 'xstate';
import type { ArcEntity } from '../entities/ArcEntity';
import type { CircleEntity } from '../entities/CircleEntity';
import { EntityName } from '../entities/Entity';
import { LineEntity } from '../entities/LineEntity';
import type { RectangleEntity } from '../entities/RectangleEntity';
import { findClosestEntity } from '../helpers/find-closest-entity';
import { polygonToSegments } from '../helpers/polygon-to-segments';
import {
addEntities,
deleteEntities,
getActiveLayerId,
getEntities,
getPickableEntities,
setEntities,
setGhostHelperEntities,
setShouldDrawHelpers,
} from '../state';
import {Tool} from '../tools';
import {eraseArcSegment, eraseCircleSegment, eraseLineSegment, getAllIntersectionPoints,} from './eraser-tool.helpers';
import type {MouseClickEvent, StateEvent, ToolContext} from './tool.types';
import { Tool } from '../tools';
import {
eraseArcSegment,
eraseCircleSegment,
eraseLineSegment,
getAllIntersectionPoints,
} from './eraser-tool.helpers';
import type { MouseClickEvent, StateEvent, ToolContext } from './tool.types';
export interface EraserContext extends ToolContext {
startPoint: Point | null;
@@ -86,7 +92,7 @@ export const eraserToolStateMachine = createMachine(
);
export function handleMouseClick(worldMouseLocation: Point) {
const closestEntity = findClosestEntity(worldMouseLocation, getEntities());
const closestEntity = findClosestEntity(worldMouseLocation, getPickableEntities());
if (!closestEntity) {
return;
}
@@ -13,6 +13,7 @@ import { getPointFromEvent } from '../../helpers/get-point-from-event';
import { pickRadius } from '../../helpers/pick-radius';
import { queryEntitiesNearPoint } from '../../helpers/spatial-index';
import {
getLayerById,
getScreenCanvasDrawController,
getSelectedEntities,
setActiveToolActor,
@@ -147,7 +148,10 @@ function cursorPoint(event: StateEvent | undefined): Point {
/** 클릭 지점에서 가장 가까운 엔티티 (선택 반경 안에 있을 때만) */
function pickEntityAt(worldPoint: Point): Entity | null {
const radius = pickRadius();
const candidates = queryEntitiesNearPoint(worldPoint.x, worldPoint.y, radius);
// 잠금 도면층(도각 등)은 집지 않는다 — 수정 도구가 참조 선을 잡으면 안 된다.
const candidates = queryEntitiesNearPoint(worldPoint.x, worldPoint.y, radius).filter(
(entity) => !getLayerById(entity.layerId)?.isLocked
);
const { distance, entity } = findClosestEntity(worldPoint, candidates);
return entity && distance <= radius ? entity : null;
}