feat(B07 CAD): 337-4b 다-2 늘이기 · 재기 · 치수 오토캐드 조작 — LENGTHEN · DIVIDE · MEASURE · DIST · DIM 류
- LENGTHEN 새 도구(lengthen-tool.ts) — 측정할 객체 [증분(DE)/퍼센트(P)/전체(T)] <마지막 방식> · 누름 = 현재 길이 알림 · 방식별 값 기억 · 변경할 객체 되풀이 · U = 이 명령 안 바꿈만 · 빈 Enter · Esc 끝 · 선 · 호 - DIVIDE · MEASURE — 기본값 없음 · 정수 2~32767 · 양수 · 블록(B) 없음 안내 · MEASURE 누른 끝부터 - DIST — 오토캐드 꼴 두 줄 기록(거리 · 각도 · 증분) · 다중 점(M) 없음 안내 - DIMLINEAR · DIMALIGNED — 빈 Enter = 객체 선택 · [문자(T)/수평(H)/수직(V)] · 치수 문자 = 기록 · 치수 객체 문자 바꿈 칸(<> = 잰 값) - DIMCONTINUE · DIMBASELINE — 되풀이 · 명령 취소(U) · 빈 Enter 끝 · DIMRADIUS · DIMDIAMETER [문자(T)] · 그 밖 치수 물음 글 - 시험 measure-acad 11 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014utrjfoW831Vc5wJUd13kL
This commit is contained in:
@@ -1,6 +1,12 @@
|
||||
/** 반지름·지름·각도·호길이·세로좌표 치수와 중심 표식 (조사표 5절) */
|
||||
/**
|
||||
* 반지름·지름·각도·호길이·세로좌표 치수와 중심 표식 (조사표 5절).
|
||||
* 오토캐드 물음 차례(337 설계 1-2) — DIMRADIUS · DIMDIAMETER = 「호 또는 원 선택:」 →
|
||||
* 「치수선의 위치 지정 또는 [문자(T)]:」 · 한 번 뒤 끝 · 그 밖 치수 = 물음 글만.
|
||||
*/
|
||||
import { Arc, Circle, Point } from '@flatten-js/core';
|
||||
import { toast } from 'react-toastify';
|
||||
import { OPT, type OptionSpec } from '../../commands/prompt';
|
||||
import { logLine } from '../../commands/run-command';
|
||||
import { getDimDecimals } from '../../commands/dim-settings';
|
||||
import type { Entity } from '../../entities/Entity';
|
||||
import { MeasurementEntity } from '../../entities/MeasurementEntity';
|
||||
@@ -8,7 +14,7 @@ import { polylineLength, sampleEntityPoints } from '../../helpers/geometry/sampl
|
||||
import { addEntities, getEntities, setEntities, setSelectedEntityIds } from '../../state';
|
||||
import { Tool } from '../../tools';
|
||||
import { arcEntity, lineEntity } from '../factories/entity-factory';
|
||||
import { createSequenceTool } from '../factories/sequence-tool';
|
||||
import { createSequenceTool, type SequenceInput } from '../factories/sequence-tool';
|
||||
import { annotationText, arrowHead, dimensionText } from './annotation.helpers';
|
||||
|
||||
interface CircularShape {
|
||||
@@ -24,7 +30,24 @@ function circularOf(entity: Entity): CircularShape | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
function radialDimension(entity: Entity, textPoint: Point, diameter: boolean): Entity[] | null {
|
||||
/** 잰 값 글(「R10.00」 · 「Ø20.00」) */
|
||||
function radialLabel(entity: Entity, diameter: boolean): string | null {
|
||||
const circular = circularOf(entity);
|
||||
if (!circular) return null;
|
||||
const value = diameter ? circular.radius * 2 : circular.radius;
|
||||
return `${diameter ? 'Ø' : 'R'}${value.toFixed(getDimDecimals())}`;
|
||||
}
|
||||
|
||||
/** 바꾼 글(`<>` = 잰 값) · 없으면 잰 값 */
|
||||
const labelWith = (measured: string, text?: string) =>
|
||||
text && text !== '<>' ? text.replaceAll('<>', measured) : measured;
|
||||
|
||||
function radialDimension(
|
||||
entity: Entity,
|
||||
textPoint: Point,
|
||||
diameter: boolean,
|
||||
text?: string
|
||||
): Entity[] | null {
|
||||
const circular = circularOf(entity);
|
||||
if (!circular) return null;
|
||||
|
||||
@@ -43,52 +66,71 @@ function radialDimension(entity: Entity, textPoint: Point, diameter: boolean): E
|
||||
return [
|
||||
lineEntity(start, textPoint),
|
||||
arrowHead(edge, circular.center),
|
||||
dimensionText(
|
||||
diameter ? circular.radius * 2 : circular.radius,
|
||||
textPoint,
|
||||
diameter ? 'Ø' : 'R'
|
||||
),
|
||||
text && text !== '<>'
|
||||
? annotationText(labelWith(radialLabel(entity, diameter) as string, text), textPoint)
|
||||
: dimensionText(
|
||||
diameter ? circular.radius * 2 : circular.radius,
|
||||
textPoint,
|
||||
diameter ? 'Ø' : 'R'
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
export const dimRadiusToolStateMachine = createSequenceTool({
|
||||
tool: Tool.DIMRADIUS,
|
||||
steps: [
|
||||
{ kind: 'entity', instructions: '반지름을 기입할 원 또는 호를 선택하십시오.' },
|
||||
{ kind: 'point', instructions: '치수 문자 위치를 지정하십시오.' },
|
||||
],
|
||||
commit: (input) => {
|
||||
const parts = radialDimension(input.entity(0), input.point(1), false);
|
||||
if (!parts) {
|
||||
toast.warn('원 또는 호를 선택하십시오.');
|
||||
return;
|
||||
}
|
||||
addEntities(parts, true);
|
||||
},
|
||||
});
|
||||
const MTEXT: OptionSpec = { key: 'MTEXT', kw: 'M', en: 'MTEXT', label: '여러 줄 문자' };
|
||||
const ANGLE: OptionSpec = { key: 'ANGLE', kw: 'A', en: 'ANGLE', label: '각도' };
|
||||
|
||||
export const dimDiameterToolStateMachine = createSequenceTool({
|
||||
tool: Tool.DIMDIAMETER,
|
||||
steps: [
|
||||
{ kind: 'entity', instructions: '지름을 기입할 원 또는 호를 선택하십시오.' },
|
||||
{ kind: 'point', instructions: '치수 문자 위치를 지정하십시오.' },
|
||||
],
|
||||
commit: (input) => {
|
||||
const parts = radialDimension(input.entity(0), input.point(1), true);
|
||||
if (!parts) {
|
||||
toast.warn('원 또는 호를 선택하십시오.');
|
||||
return;
|
||||
}
|
||||
addEntities(parts, true);
|
||||
},
|
||||
});
|
||||
/** DIMRADIUS · DIMDIAMETER — 원 · 호 → [문자(T)] → 위치 */
|
||||
function radialTool(tool: Tool, diameter: boolean) {
|
||||
const measured = (input: SequenceInput) =>
|
||||
input.has('obj') ? radialLabel(input.get<Entity>('obj'), diameter) : null;
|
||||
return createSequenceTool({
|
||||
tool,
|
||||
steps: [
|
||||
{ kind: 'entity', id: 'obj', prompt: { text: '호 또는 원 선택' } },
|
||||
{
|
||||
kind: 'text',
|
||||
id: 'txt',
|
||||
when: (input) => input.mode === 'text',
|
||||
next: 'place',
|
||||
defaultValue: '<>',
|
||||
prompt: (input) => {
|
||||
const value = measured(input);
|
||||
return {
|
||||
text: '치수 문자 입력',
|
||||
...(value === null ? {} : { default: { kind: 'enter' as const, label: value } }),
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
kind: 'point',
|
||||
id: 'place',
|
||||
prompt: { text: '치수선의 위치 지정', options: [OPT.TEXT], absent: [MTEXT, ANGLE] },
|
||||
options: { TEXT: { mode: 'text', next: 'txt' } },
|
||||
},
|
||||
],
|
||||
commit: (input) => {
|
||||
const entity = input.get<Entity>('obj');
|
||||
const text = input.has('txt') ? input.get<string>('txt') : undefined;
|
||||
const parts = radialDimension(entity, input.get<Point>('place'), diameter, text);
|
||||
if (!parts) {
|
||||
toast.warn('원 또는 호를 선택하십시오.');
|
||||
return;
|
||||
}
|
||||
addEntities(parts, true);
|
||||
logLine(`치수 문자 = ${labelWith(radialLabel(entity, diameter) as string, text)}`);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export const dimRadiusToolStateMachine = radialTool(Tool.DIMRADIUS, false);
|
||||
export const dimDiameterToolStateMachine = radialTool(Tool.DIMDIAMETER, true);
|
||||
|
||||
export const dimAngularToolStateMachine = createSequenceTool({
|
||||
tool: Tool.DIMANGULAR,
|
||||
steps: [
|
||||
{ kind: 'point', instructions: '각의 꼭짓점을 지정하십시오.' },
|
||||
{ kind: 'point', instructions: '첫 번째 변 위의 점을 지정하십시오.' },
|
||||
{ kind: 'point', instructions: '두 번째 변 위의 점을 지정하십시오.' },
|
||||
{ kind: 'point', prompt: { text: '각도 정점 지정' } },
|
||||
{ kind: 'point', prompt: { text: '첫 번째 각도 끝점 지정' } },
|
||||
{ kind: 'point', prompt: { text: '두 번째 각도 끝점 지정' } },
|
||||
],
|
||||
commit: (input) => {
|
||||
const [vertex, first, second] = input.points();
|
||||
@@ -128,8 +170,8 @@ export const dimAngularToolStateMachine = createSequenceTool({
|
||||
export const dimArcToolStateMachine = createSequenceTool({
|
||||
tool: Tool.DIMARC,
|
||||
steps: [
|
||||
{ kind: 'entity', instructions: '호 길이를 기입할 호를 선택하십시오.' },
|
||||
{ kind: 'point', instructions: '치수 문자 위치를 지정하십시오.' },
|
||||
{ kind: 'entity', prompt: { text: '호 또는 폴리선 호 세그먼트 선택' } },
|
||||
{ kind: 'point', prompt: { text: '호 길이 치수 위치 지정' } },
|
||||
],
|
||||
commit: (input) => {
|
||||
const entity = input.entity(0);
|
||||
@@ -146,8 +188,8 @@ export const dimArcToolStateMachine = createSequenceTool({
|
||||
export const dimOrdinateToolStateMachine = createSequenceTool({
|
||||
tool: Tool.DIMORDINATE,
|
||||
steps: [
|
||||
{ kind: 'point', instructions: '좌표를 기입할 피처 위치를 지정하십시오.' },
|
||||
{ kind: 'point', instructions: '지시선 끝점을 지정하십시오.' },
|
||||
{ kind: 'point', prompt: { text: '피쳐 위치 지정' } },
|
||||
{ kind: 'point', prompt: { text: '지시선 끝점 지정' } },
|
||||
],
|
||||
commit: (input) => {
|
||||
const [feature, leaderEnd] = input.points();
|
||||
|
||||
Reference in New Issue
Block a user