Tavotto
AI drew your research figure. Tavotto makes it publication-ready: edit matplotlib figures on a canvas, lay out in mm, check journal rules. Free, open source.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證설치 없이 STP·STEP 3D 모델을 열고 부품·조립 구조와 거리를 확인하는 무료 STEP 뷰어 (OpenCAD)
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗STEP(ISO 10303-21, AP203·AP214·AP242) 파일을 브라우저 안에서 읽고 B-rep 곡면을 삼각화해 3D로 보는 앱과 그 해석기입니다.
해석기는 DOM·WebGL에 기대지 않아 웹 워커에서 돌고, 결과 장면(Scene3d)은 opencad-viewer3d로 그립니다.
다른 CAD 커널이나 STEP 라이브러리를 쓰지 않고 공개 명세만 보고 새로 작성했습니다.
앱 주소(배포 예정): https://gyutae-kim.github.io/opencad-step/
함께 쓰는 저장소: opencad-viewer3d(3D 뷰어 코어) · opencad-nc · opencad-skp
unpackStep(src/archive.ts).
STEP-XML(ISO 10303-28, .stpx)은 지원하지 않는다고 알려 줍니다.StepProductNode)meta.layersStepProductNode.props,
자리의 세계 변환 → StepProductNode.matrix(밀도는 단위를 따라 kg/m³로, 단위가 없으면 값 크기로 g/cm³·kg/m³를 짐작)scene.lines(점은 scene.points)meta.pmisrc/strokefont.ts — 숫자·영문·기호 ± ° Ø ×·GD&T 기호)로 선분으로 그립니다.
글자 높이는 TEXT_LITERAL_WITH_EXTENT 크기, 주석 양식의 BOX_HEIGHT, 없으면 2.5. 맞춤(centre·right·top)을 따릅니다(src/pmitext.ts)src/app/glyphs.ts·src/glyphtrace.ts — 글꼴 파일을 내려받지 않고, 글자마다 한 번만 그립니다). 다른 PMI 선과 같은 선 묶음이라 확대·단면·숨김·강조·그림 저장을
그대로 따릅니다. 해석기만 쓸 때는 glyphs 선택으로 글자 모양을 주고, 주지 않거나 기기에 그 글자 글꼴이 없으면 빈 상자로 그립니다semantic[].faces(면 STEP 번호)meta.pmi.views(src/savedviews.ts)meta.faceTables·meta.meshFaceTable(면 단위 고르기)Mesh3d.edges의 선분 → B-rep 모서리 EDGE_CURVE, 곡선 종류 직선·원·타원·B-스플라인, 원 중심·법선·반지름·호 각, 곡선 길이 적분,
곡선 모서리 두 끝의 접선 — B-rep 곡선의 1차 도함수, 모서리 방향, 원호·타원 호의 틀 x축과 두 끝 매개변수 각(한 바퀴 원은 없음, 한 바퀴 타원은 틀 x축만)과
B-스플라인 정의 — 차수·매듭·조절점·가중치·모서리 매개변수 구간, 수 512개까지 curveStart·curves)
→ meta.edgeTables·meta.meshEdgeTable(모서리 고르기·개체 측정·측정 접선 잠금 — 이음선은 윤곽선에 없어 표에도 없음)Mesh3d.closed = true — 단면에서 잘린 면을 채웁니다props(src/massprops.ts).
발산 정리로 입체 적분을 겉면 적분으로 바꾸고, 면마다 곡면 매개변수 공간에서 그린 정리로 경계 적분으로 바꿉니다. 평면·원기둥·원뿔·구·원환과
회전 곡면(직선·원·타원·B-스플라인 윤곽 — 윤곽이 축과 한 평면에 있지 않아도 됨)은 안쪽 적분이 닫힌 식이라 직선·원·타원 모서리로 된 입체는
반올림 오차 수준(상대 1e-14 안팎)으로 맞습니다. B-스플라인 윤곽은 매듭 구간마다 다항식이라 매개변수 공간 직선 토막을 매듭에서 나눠 적분합니다.
B-스플라인 곡면과 B-스플라인 곡선을 민 곡면도 매듭 구간마다 (u, v)의 다항식이라, 안쪽 적분을 u 매듭에서 나눈 가우스로(u 구간이 많으면 다 덮는 구간 적분의
누적 합을 v의 다항식으로 미리 구해 둠), 매개변수 공간 직선 토막을 u·v 매듭에서 나눈 가우스로 정확히 구합니다. 모서리 곡선 토막은 곡선 매듭에서 나눠
7–15점 가우스–크론로드로 적분하고 둘이 어긋나면 반으로 나눕니다. 곡선 위 점은 토막 끝의 (u, v) 사이 짐작에서 가우스–뉴턴으로 곧장 곡면에 되짚고
(마지막 점의 편도함수를 그대로 쓰고, 반올림 수준에서는 걸음을 줄여 다시 구하지 않음), 곡면에서 되짚기 허용치보다 멀 때만 격자 짐작까지 합니다.
가중치가 있는 B-스플라인(NURBS)은 점을 더 쓰고 점이 적은 규칙과의 차이를 어림 오차로 남깁니다
(NURBS 원기둥에서 어림 오차 상대 3e-12, 실제 오차 1e-16). 원·타원을 민 곡면은 원기둥처럼 닫힌 식입니다. 오프셋 곡면처럼 적분하지 않는 곡면과
모서리 곡선이 곡면에서 멀어 곡면 적분의 어림 오차가 삼각형 쪽보다 큰 면은 그 면만 삼각형으로 재고
꺾인 선과 곡선 사이 띠를 더해 겉면을 닫으며, 삼각형과 곡면 사이 거리로 어림 오차를 함께 남깁니다. 삼각형 부피와 크게 어긋나면 삼각형 값으로 되돌리고,
적분이 오래 걸리면(기본 1.5초 + 삼각화 시간의 절반을 넘으면) 남은 입체는 삼각형 값과 어림 오차를 씁니다(propsBudget, meta.stats.propsTimedOut).
적분은 삼각화와 떼어 둡니다: 삼각화하면서 면마다 적분할 거리(곡면, 매개변수 공간 다각형, 경계 모서리와 곡선 매개변수)만 남기고
MassPropsJob(src/propsjob.ts)이 따로 적분합니다. 앱 워커는 문서를 보인 뒤 면 단위로 나눠 적분하고, stepToScene은 예전처럼 끝까지 적분한 장면을 돌려줍니다orientFaces — 덩어리마다 부피 부호로
바깥을 정해 빈 곳 BREP_WITH_VOIDS는 안쪽으로). 단일면으로 그리는 닫힌 입체에서 면이 사라지지 않습니다clipAll — 엇갈린 자리의
삼각형은 뒤집히지만 띠 너비만큼이라 아주 작습니다) 이웃 면과 틈이 생기지 않습니다TRUNCATED_WARNING을 두고, 아는 곡면을 가리키는 개체가 없어
못 만든 면은 "지원하지 않는 곡면"이 아니라 "읽지 못함(가리키는 개체가 없거나 값이 잘못됨)"으로 적습니다origin으로 빼고 담아 float32로도 떨리지 않습니다(그 밖에는 예전과 같습니다)watertightness, meshArea, meshVolume)npm run sweep — 개발 절) 예외·실패 면 0, 닫힌 껍질 3,119개가 모두 틈 없이 닫히는 것을 확인했습니다(보통 품질에서
삼각형 감기가 어긋난 입체 72개 파일 → 0개, 접힌 삼각형이 0.1% 넘는 파일 35개 → 6개). 앱의 "아주 세밀" 품질에서 가장 오래 걸리는 파일(면 2,730개,
삼각형 274만 개)은 12초쯤 걸립니다(데스크톱, 고치기 전 20초). 같은 표본(보통 품질)의 닫힌 입체 3,114개 가운데 2,808개는 질량 속성이 곡면 적분으로 정확하고,
301개는 B-스플라인 같은 면이 섞여 어림 오차가 많아야 ±0.083%입니다(나머지 5개는 지름 0.4 µm 남짓한 퇴화 입체라 삼각형 값). 질량 속성은 문서를 연 뒤
따로 적분하므로 문서 여는 시간은 적분을 넣기 전과 같습니다(표본 442개를 번갈아 잰 합: 적분 없이 8.9초, 지금 9.1초, 열면서 함께 적분하면 11.9초).
회전 곡면도 적분한 뒤 지금 남은 표본 1,864개(보통 품질)에서는 근삿값 입체가 197개 → 177개로 줄었습니다(회전 곡면이 든 32개 파일 가운데 20개가 정확,
12개는 B-스플라인 면 등이 섞여 어림 오차만 줄어듦). B-스플라인·민 곡면까지 적분하자 근삿값 입체가 177개 → 166개(파일 147개 → 136개), 가장 큰 어림 오차가
±0.083% → ±0.017%가 되었습니다. 값이 바뀐 입체 91개는 모두 예전 값 ± 어림 오차 안이고, 그 가운데 88개는 어림 오차가 좁아졌습니다(예: ±0.013% → ±0.00007%).
근삿값이던 그 파일들의 B-스플라인·민 곡면 642개 가운데 577개(가중치 있는 면 284개 가운데 264개)를 곡면 적분하고 65개는 삼각형 쪽 어림 오차가 더 좁아 삼각형으로 잽니다.
질량 속성 적분 시간은 그 147개 파일에서 합 3.1초 → 5.1초(중앙 7 → 13 ms, 가장 긴 파일 0.37 → 0.47초)이고 문서 여는 시간은 그대로입니다.
남은 근삿값은 대부분 모서리 곡선(교선을 맞춘 곡선)이 곡면에서 조금 떨어져 생긴 것이라, 곡선 위 점을 곡면의 가장 가까운 점으로 다듬은 자리를 면의 경계로 적분하고
그 경계에서 곡선까지 곧은 띠를 더합니다. 이웃 면도 같은 곡선까지 이으므로 겉면이 닫히고, 어림 오차는 곡선과 곡면 사이 거리를 반지름으로 한 관의 부피(모형의 허용 오차)로 줄어듭니다.
모서리 곡선이 꼭짓점을 조금(1e-4 mm 안팎) 비껴 지나 면 경계가 꼭짓점마다 끊긴 곳도 꼭짓점 둘레를 메워 잇습니다.
그러자 근삿값 입체가 166개 → 29개(파일 136개 → 19개), 가장 큰 어림 오차가 ±0.017% → ±0.000011%가 되었습니다. 값이 바뀐 입체 292개(파일 284개)는 모두
예전 값 ± 어림 오차 안입니다. 적분 시간은 근삿값이던 136개 파일에서 합 3.5초 → 4.1초(중앙 7.0 → 7.5 ms, 가장 긴 파일 0.38 → 0.42초)입니다.
"아주 세밀" 품질에서도 시간 한도를 넘는 파일이 없고(한도를 가장 많이 쓴 파일이 31%), 값은 보통 품질과 어림 오차 안에서 같습니다(B-rep 입체 2,887개의 상대 차 중앙값 1e-15).
시간 한도(1.5초 + 삼각화 시간의 절반)는 입체를 시작할 때 보므로 입체가 하나인 파일은 한도에 걸리지 않고 끝까지 적분합니다(적분이 가장 긴 두 파일이 그렇습니다).
B-스플라인 면 적분에서 곡선 위 점 되짚기를 다듬자(점마다 곡면 계산 8번쯤 → 3번쯤) B-스플라인 면이 많은 파일의 적분 CPU 시간이 30.stp·.step·.p21 파일이나 압축 STEP(.stp.gz·.stpZ·STEP이 든 .zip)을 고르거나,
창 어디에나 끌어다 놓습니다(여러 개를 놓으면 첫 STEP 하나). 압축은 워커가 "압축 푸는 중" 단계로 풀고, 정보 탭에 압축 형식·ZIP 항목·푼 크기를 보입니다.
.stpx(STEP-XML)는 지원하지 않는다는 안내가 뜹니다. 같은 Part 21 글인 IFC(건축 BIM, FILE_SCHEMA가 IFC…)는 다 읽기 전에 IFC 뷰어로 열라고 알리고,
끊긴 파일은 형상이 없으면 그것을 까닭으로, 일부만 읽혔으면 "파일을 다시 받아 여십시오" 알림을 띄웁니다.
"예제 열기"는 우리가 만든 작은 조립 모형(받침판·블록 둘·핀 묶음, 레이어 셋, 받침판 PMI)을 엽니다.
한 번에 문서 하나를 열며 새로 열면 바꿉니다. 큰 파일은 해석 중 덮개의 "취소"(또는 Esc)로 멈출 수 있습니다.opencad-step — 목록 recent, 파일 recent-data)에 새것부터 8개까지 남깁니다(60MB보다 큰 파일과 예제·?open= 주소로 연 것은 빼고).
시작 화면의 "최근 문서"에서 이름·크기·시각을 보고 눌러 다시 열며, ✕로 하나씩 또는 "모두 지우기"로 지웁니다. 서버로 보내지 않고, 비공개 창처럼 저장소를 못 쓰면 목록 없이 그대로 씁니다.
목록을 그릴 때는 파일 바이트를 읽지 않고, 누른 파일 하나만 읽습니다. 저장해 둔 파일이 없으면 목록에서 지우고, 잠깐 못 읽으면 항목을 남겨 다시 누를 수 있게 합니다.
휴대폰 브라우저가 뒤로 간 탭을 버렸다가 다시 불러와도 파일 앱을 다시 거치지 않고 엽니다.setRenderOptions({ hiddenEdges })),
외곽선 강조(화면 공간 실루엣 — profiles), 부품 색 구분, 분해 보기(아래).
와이어프레임·숨은선 제거는 B-rep 모서리만 그리고(삼각형 변 없음 — 코어 triangleEdges) 모서리와 같은 1화소 외곽선을 늘 켭니다(코어 v0.7.2 profiles: { width: 1 }).
모서리가 없는 매끈한 면(원환 고리·구)도 테두리로 보이고, 이 두 모드에서 "외곽선 강조"는 켜진 채 잠깁니다(다른 모드로 가면 고른 값으로).
키는 캔버스에 초점이 없어도(입력 칸 제외) 듣습니다. Tab 키로 3D 보기에 초점이 오면 보기 안쪽에 테두리가 보입니다. 마우스·터치로 누르면 테두리가 사라지고(키보드로 초점을 준 뒤 눌러도), Tab으로 다시 오면 보입니다(코어 v0.9.1).import { stepToScene } from 'opencad-step';
const scene = stepToScene(bytes, {
name: 'part.step',
onProgress: (fraction, stage) => console.log(fraction, stage),
// 선택(모두 기본 true): curves — 와이어프레임·곡선 형상, pmi — 표현 PMI 선·의미 PMI, faceTable — 면 표
// glyphs?: (ch) => { strokes, advance } | null — 내장 획 글꼴에 없는 PMI 글자(한글 등)의 모양(글자 칸: 대문자 높이 6, 기준선 0). 없으면 빈 상자
});
// scene: Scene3d (opencad-viewer3d의 Viewer3d.setScene에 넘긴다), scene.meta에 제품 나무·단위 등
// scene.lines: 곡선 형상(group = 부품 이름, 나무 마디의 lineIds)과 표현 PMI 선(group 없음, meta.pmi.presentations의 id)
// meta.layers?: 레이어(이름·설명·처음 보이기·meshIds·lineIds) — Mesh3d.group은 그대로 부품 이름
// meta.pmi?: { presentations, semantic }
// meta.faceKinds·faceTables·meshFaceTable?: 그물 삼각형 → B-rep 면(src/brep.ts FaceTableData)
// meta.edgeKinds·edgeTables·meshEdgeTable?: 윤곽선 선분 → B-rep 모서리(src/brep.ts EdgeTableData) — 곡선 정의는 edgeCurve(표, 번호, edgeKinds)로 읽고
// nearestOnCurve(정의, 점)로 곡선 위 가장 가까운 매개변수·점·접선을 구한다(src/edgecurve.ts, 좌표는 묶음 origin을 뺀 그물 좌표)
// faceTables[i].props?: 닫힌 입체의 질량 속성 [부피, 1차 모멘트 3, 2차 모멘트 6, 기준점 3, 부피 어림 오차, 구한 길](src/massprops.ts PROPS_*)
// — 선택 props: false로 끄고, propsBudget: { minMs, share }로 적분 시간 한도를 바꾼다
// Mesh3d.closed: 닫힌 입체(단면 채우기) · Mesh3d/LineSet3d/PointSet3d.origin?: 큰 좌표일 때 묶음 원점(positions는 원점 기준)
// scene.warnings?.[0] === TRUNCATED_WARNING(같은 입구에서 가져옴)이면 끊긴 파일
// 질량 속성을 나중에 구하기: 장면을 먼저 쓰고, 적분은 조각으로 나눠(run(ms)이 true면 끝) 면 표에 넣는다
import { applyProps, stepToSceneDeferred } from 'opencad-step';
const { scene: shown, props } = stepToSceneDeferred(bytes);
while (props && !props.run(40)) applyProps(shown, props.take(), props); // 사이사이 다른 일
if (props) applyProps(shown, props.take(), props);
// 압축 STEP(gzip·ZIP)은 먼저 푼다(비동기, DecompressionStream)
import { unpackStep } from 'opencad-step';
const { bytes: step } = await unpackStep(fileBytes);
| 경로 | 내용 |
|---|---|
index.html, public/ | 앱 진입 페이지, 아이콘, 앱 정보(공유 받기·파일 열기) |
tools/site.mjs, tools/sw-source.mjs | 이 앱의 사이트 설정(앱 정보 원본·서비스 워커 판 이름 짓기 — vite.config.ts와 시험이 같이 씀)과 오프라인 서비스 워커 본문(미리 담은 것 쓰기·공유 받기). 언어 페이지·검색 정보·사이트맵·언어별 앱 정보·dist/sw.js는 공용 사이트 도구의 Vite 플러그인이 이 설정으로 만든다 |
site/i18n-core.mjs, site/i18n.mjs, site/locales/ | 공용 번역기에 이 앱의 사이트 정보(site/metadata.json)를 넘기고 사전을 넣는다 |
src/app/main.ts, src/app/app.ts, src/app/core.ts | 앱 진입점과 화면 골격(제목 막대·보기 도구 막대·3D 보기·패널·상태 막대), 열기·고르기·면 고르기·보이기·키, 3D 뷰어 코어·곡선 접선 잠금 나눠 받기 |
src/app/toolbar.ts, src/app/panel.ts, src/app/sectionbar.ts, src/app/dialog.ts, src/app/resize.ts, src/app/menu.ts, src/app/dom.ts, src/app/icons.ts, src/app/styles.css | 보기 도구 막대, 제품·속성·레이어·PMI·정보 패널, 단면 막대·손잡이, 대화 상자, 패널 크기 손잡이, 메뉴(단추 아래·화면 점), DOM 도우미, 아이콘, 스타일 |
src/app/edges.ts, src/app/entmeasure.ts, src/app/entpick.ts, src/app/looks.ts, src/app/explode.ts, src/app/explodebar.ts, src/app/snap.ts, src/app/tangent.ts, src/app/curvesnap.ts, src/app/facesnap.ts | 순수 로직: 모서리 찾기·길이·원 중심·붙잡기, 두 개체 사이 해석적 거리·각, 누른 것 → 개체·최소 거리·덧그림(이 둘은 코어 조각으로 받음), 부품 겉모습(불투명도·흐리게·부품 색·분해 이동 걸기, 반투명 보기 판정), 분해 계획(조립 단계별·한꺼번에 — 방식 단추·단계 글과 함께 문서를 열 때 받음), 두 점 측정 붙잡기 선택(원·원호 중심, 모서리 가운데 점, 추론 붙잡기)과 붙잡은 종류 이름, 곡선 모서리 위(끝·가운데)의 접선 잠금과 측정 붙잡기 점을 B-rep 곡선 위로 다듬기(수직 발·모서리 위 점·두 곡선의 교차점·축과 곡선의 교차)·곡선 길이 가운데 점, 축이 면을 뚫는 점과 붙잡지 않은 면 위 점을 B-rep 곡면 위로 다듬기(셋 다 문서를 열 때 받음) |
src/app/doc.ts, src/app/tree.ts, src/app/faces.ts, src/app/visibility.ts, src/app/format.ts, src/app/display.ts, src/app/files.ts, src/app/keys.ts, src/app/theme.ts | 순수 로직: 문서 모델·meta 읽기·다시 삼각화 때 상태 잇기·고르기 단위(부품·몸체)와 여러 개 고르기, 제품 나무 펼침·고르기·이름 거르기, 면 찾기·경계·넓이·PMI 면 범위, 보이기(눈 단추·레이어·PMI·격리), 글 만들기, 표시 설정(단위·소수 자리·곡면 품질·수 꼴), 파일 이름·주소 인자, 키 규칙, 테마 |
npm install
npm run dev # http://localhost:4402/ (예제 바로 열기: /?sample)
npm run typecheck
npm test # 해석기 시험(tests/*.test.ts)과 앱 순수 로직 시험(tests/app/)
npm run build # tsc --noEmit && vite build → dist/
npm run preview # 빌드 결과 보기
시험은 tests/stepText.ts(본문은 src/app/stepText.ts)로 만든 작은 STEP 글로 돌립니다(외부 STEP 파일은 넣지 않습니다).
측정 방향 잠금 시험(tests/app/measurelock.test.ts)은 가짜 DOM·WebGL2(tests/app/fakeview.ts — 코어 저장소의 시험 도구를 줄여 옮김)로 실제 코어 뷰어를 만들어
앱의 붙잡기 선택과 포인터·키 사건을 넣고 코어가 잠그는 방향을 봅니다. 곡선 접선 잠금 시험(tests/app/measuretangent.test.ts)도 같은 방식으로
원기둥 테두리 원·타원 호·B-스플라인 모서리(tests/app/curvescene.ts)의 끝과 가운데(테두리 30° 지점·타원 호 가운데 점·B-스플라인 중간 꼭짓점)에서
앱이 코어보다 먼저 잠그는 접선을 봅니다. 곡선 위 가장 가까운 매개변수는 곡선 위 점에서 조금 비킨 점으로 1e-9 안에 맞는지 봅니다(tests/edgecurve.test.ts).
측정 붙잡기 다듬기 시험(tests/app/measurerefine.test.ts)도 실제 코어로 B-스플라인 판 모퉁이에서 원기둥 테두리로 내린 수직 발이 원 위 1e-9이고 거리 값도 그 발까지인지,
타원·B-스플라인 토막 위 점이 곡선 위인지, 직선 모서리는 그대로인지, 곡선 길이 가운데 점, 다듬은 첫 점·커서 아래 점에서의 접선 잠금을 봅니다
(순수 계산 — 꼭짓점 매개변수, 법선으로 비킨 첫 점의 발, 광선이 지나는 점, 곡선 길이 가운데 — 은 tests/app/curvesnap.test.ts).
코어 0.15.0 다듬기 시험(tests/app/measurecross.test.ts)은 원기둥 테두리와 3D로 한 점에서 만나는 곧은 모서리·세로 원·B-스플라인과 멀리 떨어진 판(tests/app/crossscene.ts)에서
꺾은선 토막에 내린 발이 모두 토막 밖인 먼 첫 점의 원 위 발과 거리, 세 교차점과 거리가 1e-9 안인지, 곡선 붙잡기가 없으면 두 후보가 없는지를 실제 코어로 봅니다
(순수 계산 — 교차점 식·가우스–뉴턴, 같은 평면의 직선과 원, 비켜 지나가는 둘·같은 모서리·함께 쓰는 꼭짓점·두 곧은 모서리는 없음, 열린 수직 발 — 은 tests/app/curvecross.test.ts).
코어 0.18.0 시험(tests/app/measureaxis.test.ts)은 원기둥과 옆 삼각 판에서 첫 점 X·Y축과 테두리의 교차가 원 위이고 축 위 정확히인지, 곡선 붙잡기가 없으면 현 위 점,
두 선택을 끄면 후보가 없고 첫 점 전에는 켜도 같은지, 끌어온 축과 테두리의 교차, 첫 점 X축이 옆면을 뚫는 점을 실제 코어로 봅니다
(순수 계산 — 원·곧은 모서리·타원·B-스플라인과 축의 교차, 비켜 지나가는 축·호 범위 밖 — 은 tests/app/axisedge.test.ts,
축·잠근 선이 B-스플라인에 접하는 자리 — 접점, 평평한 곡선, 허용치 밖·안 틈, 두 근, 접점이 모서리 끝 바로 밖 — 은 tests/app/axistouch.test.ts).
거리 글상자가 비킬 자리 시험(tests/app/labelavoid.test.ts)은 3D 보기의 측정 띠·위 띠·단면 막대만 고르고 뷰 큐브는 코어 viewCubeRect로 받는지(큐브를 끄면 빼는지),
크기가 바뀌면 다시 알리고 정밀 조준 자리와 합치는지,
헤드리스에서 잰 휴대폰 띠·큐브 자리를 코어 자리 고르기(placeMeasureLabel)에 넘기면 가리던 글상자가 비키고 겹치지 않던 자리는 그대로인지를 봅니다.
코어 0.19.0 시험(tests/app/measurelockface.test.ts)은 같은 장면에서 잠근 X·Y축과 테두리의 교차가 원 위인지, 잠근 X축과 잠그지 않은 첫 점 X축이 옆면을 뚫는 점이 원기둥 위인지,
축이 아닌 방향으로 잠근 선이 테두리와 만나는 점·옆면과 B-스플라인 지붕을 뚫는 점이 곡선·곡면 위인지(0.20.0), 두 선택을 끄면 0.18.0 그대로이고 잠그지 않았을 때는 켜도 같은지,
B-스플라인 지붕과 민 곡면 원기둥(tests/app/facescene.ts)에서 워커가 남긴 곡면 정의로 곡면 위인지를 실제 코어로 봅니다(순수 계산 — 원기둥·원뿔·구·원환 식,
B-스플라인·밀기·회전 곡면의 뉴턴법, 극점 둘레 다시 풀기와 먼 근·비켜 가는 직선, 단위 배율·묶음 원점, 곡면 정의 복제·되살리기, 잘린 면의 경계 — 은 tests/app/facesnap.test.ts,
워커가 들고 있는 곡면 정의의 격자 버리기는 tests/app/propsflow.test.ts).
코어 0.20.0 시험(tests/app/measureopen.test.ts)은 기울인 원판·타원 판·B-스플라인 판 위 점(한 토막 가운데 매개변수) 위 판 꼭짓점의 Z축이 곡선 평면을 뚫는 자리를
열린 교차로 곡선 위에 붙이는지(잠근 Z축도, 곡선 붙잡기가 없으면 교차 없음), 축이 아닌 방향·곡선 접선으로 잠근 선이 원 테두리와 만나는 점이 원 위인지를 실제 코어로 봅니다.
코어 0.21.0~0.23.0 시험 둘은 실제 코어로 봅니다. tests/app/onface.test.ts는 붙잡지 않은 원기둥 옆면·B-스플라인 지붕 위 점이 곡면 위("곡면 위 점")이고 평면 윗면은 그대로인지,
원기둥 실루엣 둘레를 스치는 광선(평범한 원기둥과 민 곡면 원기둥)에서 코어 점에 더 가까운 나가는 근 대신 들어가는 근을 주는지, 판 구멍 안쪽 벽에서 맞은편 벽 위 근인지,
축이 원기둥 삼각형을 비켜 가며 곡면만 뚫는 열린 후보(0.22.0)도 같은 교점인지, 곡면 정의를 받기 전에 미리 본 축과 지붕의 교차가 다듬기 기억을 비운 뒤 곡면 위로 옮기는지를 봅니다.
는 잠근 X축이 끌어온 점의 Y축과 만나는 점·끌어온 점과 나란한 자리와 그 이름(4개 언어 사전), 끄면 0.20.0 그대로인지,
앞 상자를 반투명하게 하면 그 너머 뒤 상자 면을 고르고 측정하며 반투명이 아니면 그대로인지,
측정 중 반투명 보기를 켜고 꺼도(0.24.0) 찍은 점·화살표 잠금·Shift 잠금·끌어온 점이 남고 붙잡기 선택을 다시 주지 않으며 그 자리 미리 보기가 앞 상자 너머로 바뀌는지를 봅니다
(반투명 보기 판정은 ). 는 개체 측정의 "최소 거리 ≈"와 "부품 사이 최소 거리 ≈" 덧그림 글상자가
같은 선분이면 뒤의 것이 비키고 앞의 것은 제자리인지, 겹치지 않으면 하나씩 그릴 때와 같은 자리인지를 실제 코어로 봅니다.
질량 속성 시험()은 해석적 입체와 비선형·비튼 매개변수 B-스플라인 평면 상자, 위가 B-스플라인인 블록, B-스플라인 곡선을 민 기둥,
이음선 모서리 없는 닫힌 B-스플라인 관, NURBS 원기둥을 닫힌 식과 견줍니다(안쪽 적분이나 직선 토막을 매듭에서 나누지 않으면 실패하는 입체를 함께 둡니다).
모서리 곡선이 곡면에서 떨어진 원기둥·구 조각·B-스플라인 관과 곡선이 꼭짓점을 비껴 지나는 반원 기둥도 닫힌 식과 견줍니다(띠나 꼭짓점 메우기를 빼면 실패합니다).
물결 친 B-스플라인 조각 위 (u, v) 원을 경계로 한 면은 극좌표 가우스로 구한 정확한 값과 견주고, 곡선 위 점마다 곡면 계산이 4번 밑인지(예전 길은 5.3번),
곡선이 곡면에서 되짚기 허용치보다 멀면 격자 짐작까지 해도 같은 값인지, 닫힌 B-스플라인 입체를 적분하는 동안 곡면의 되짚기를 부르지 않는지 봅니다.
압축 시험은 (시험용 ZIP 글쓴이, node:zlib)로 gzip·ZIP을 만듭니다.
확인용으로 받은 공개 STEP 파일이나 임시 결과는 git이 무시하는 에만 둡니다.
3D 뷰어 코어는 으로 받습니다 — 올릴 때는
처럼 태그를 주어야 잠금 파일의 커밋이 바뀝니다(그냥 은 옛 커밋을 남깁니다).
B-rep 면 그물에는 (코어 0.7.1부터)를 둡니다(와이어프레임·숨은선에 삼각형 변 없이 B-rep 모서리만). 삼각형 형식(TESSELLATED 등)과
다각 고리(POLY_LOOP) 면이 든 그물은 모서리 선이 없어 삼각형 변을 그대로 그립니다.
개발 서버가 옛 코어를 미리 묶어 둔 채라면 로 다시 묶습니다.
첫 화면 JS를 줄이려고 코어 입구( — 뷰어·그리기·고르기)는 열기 상자를 열거나 파일을 끌어 오거나 문서를 열기 시작할 때 의 로 받습니다.
받는 것은 코어 입구와 뷰어를 만든 뒤에만 쓰는 앱 모듈(정밀 조준 , 개체 측정 )을 묶은 조각입니다(요청은 그대로 하나).
앱 입구에서 닿는 모듈은 코어의 작은 모듈(·· 등)만 값으로 가져오고 코어 입구는 타입으로만 가져옵니다
(가 앱 입구의 정적 가져오기 그래프를 훑어 확인합니다. 숫자 키 표 도 코어 0.10.0부터 작은 모듈에서 가져옵니다).
보기 링크의 고른 것 낱말()과 STL·OBJ·CSV 내보내기()도 첫 화면 JS에 넣지 않고 로 받습니다 — 문서를 열 때 미리 받아 두어
눌렀을 때 기다리지 않습니다(같은 시험이 확인). 그래서 몸체 줄·보기 링크 고른 것·간섭 안에 듦을 넣은 뒤에도 첫 화면 JS는 gzip 86.4 kB로 그 전(86.0 kB)과 거의 같습니다.
측정 곡선 접선 잠금()도 뷰어를 만들 때 의 로 받습니다(같은 시험이 확인 — 받기 전에는 곡선 끝에서도 코어 판정만).
곡선 접선 잠금과 정밀 조준 글상자 비키기를 넣은 뒤 첫 화면 JS는 gzip 86.1 kB에서 86.7 kB가 되었고, 접선 조각은 2.3 kB입니다.
곡선 가운데 접선 잠금은 곡선 계산(, NURBS 곡선 계산)과 함께 접선 조각에만 들어가 첫 화면 JS는 그대로(gzip 86.7 kB, 조각 이름만 바뀜)이고
접선 조각이 gzip 2.5 kB에서 6.8 kB가 되었습니다.
측정 붙잡기 다듬기와 곡선 길이 가운데 점()도 접선 조각에 넣어(코어에 을 주는 것은 조각을 받은 뒤 — 받기 전에는 꺾은선 위 점 그대로)
첫 화면 JS는 gzip 86.7 kB에서 87.0 kB(앱 연결·이름만), 접선 조각은 6.8 kB에서 9.6 kB가 되었습니다.
분해 계획과 분해 막대의 방식 단추·단계 글(·)도 문서를 열 때 로 받습니다(같은 시험이 확인 — 받기 전에는
막대 껍데기만 있고, 분해를 켜면 받은 뒤 겁니다). 조립 단계별 분해와 선 형상 몸체 줄을 넣은 뒤 첫 화면 JS는 gzip 86.98 kB에서 87.58 kB(막대 껍데기·보기 링크 ·선 형상 줄 —
분해 계산을 첫 화면에 두었을 때는 88.01 kB)가 되었고, 분해 조각은 1.6 kB입니다.
코어 0.15.0과 두 곡선의 교차점·원호 끝 매개변수를 넣은 뒤에도 첫 화면 JS는 gzip 87.59 kB 그대로(파일 크기도 같음)이고, 교차점 계산은 접선 조각에만 들어가
접선 조각이 gzip 9.56 kB에서 11.72 kB, 코어 조각이 64.54 kB에서 65.83 kB가 되었습니다.
코어 0.16.0·선분 식별자·끌어온 축과 B-스플라인 곡면 질량 속성을 넣은 뒤 첫 화면 JS는 gzip 87.43 kB에서 87.61 kB(물리 속성 도움말 글·끌어온 축 이름)이고,
접선 조각이 11.73 kB에서 12.47 kB, 코어 조각이 65.54 kB에서 67.15 kB, 해석 워커가 71.26 kB에서 76.40 kB(곡면 적분)가 되었습니다.
코어 0.17.0과 질량 속성 겉면 닫기(띠·꼭짓점 메우기)를 넣은 뒤 첫 화면 JS는 gzip 87.61 kB에서 87.90 kB(끌어온 축 이름 가르기)이고,
코어 조각이 67.15 kB에서 68.59 kB, 해석 워커가 76.40 kB에서 78.45 kB가 되었습니다(접선 조각은 12.46 kB 그대로).
코어 0.18.0과 첫 점 축과 모서리·면, 축 교차 다듬기를 넣은 뒤 첫 화면 JS는 gzip 87.90 kB에서 87.97 kB(축 위 점 이름 가르기)이고,
교차 계산은 접선 조각에만 들어가 접선 조각이 12.46 kB에서 13.12 kB, 코어 조각이 68.59 kB에서 69.97 kB가 되었습니다(해석 워커는 그대로).
코어 0.19.0과 잠근 선 교차, 축이 곡면을 뚫는 점 다듬기를 넣은 뒤 첫 화면 JS는 gzip 87.97 kB에서 88.52 kB(잠근 선 교차 이름·곡면 정의 요청)이고,
면 다듬기()는 접선 조각에 들어가 접선 조각이 13.12 kB에서 16.05 kB(NURBS 계산이 곡면 조각과 함께 쓰려고 이 조각으로 옮겨 옴),
곡면 정의 되살리기와 곡면 계산( — ·)은 접선 조각이 로 받는 곡면 조각(7.42 kB)에 들어갑니다.
코어 조각은 69.97 kB에서 70.53 kB, 해석 워커는 약 0.7 kB(곡면 정의 남기기·보내기) 늘었습니다.
코어 0.20.0과 극점 둘레 다시 풀기, 워커의 곡면 정의 격자 버리기를 넣은 뒤 첫 화면 JS는 gzip 88.65 kB 그대로입니다(첫 화면 모듈은 바뀌지 않았고,
0.19.0 때 88.52 kB에서 늘어난 몫은 그 뒤 올린 공용 사이트 도구의 계측). 접선 조각이 16.05 kB에서 16.55 kB(다시 풀기), 곡면 조각이 7.42 kB에서 7.49 kB,
코어 조각이 70.53 kB에서 71.84 kB(열린 교차) 늘었습니다.
거리 글상자 비키기와 접점 다듬기는 접선 조각에 들어가 첫 화면 JS는 gzip 88.65 kB에서 88.68 kB(조각 연결 몇 줄)이고, 접선 조각이 16.55 kB에서 17.23 kB가 되었습니다.
B-스플라인 면 적분의 되짚기 다듬기는 해석 워커에 들어가 첫 화면 JS는 gzip 88.68 kB 그대로이고, 곡면 조각이 7.49 kB에서 7.54 kB(곡선의 점·도함수를 함께 구하기)가 되었습니다.
코어 0.23.0과 곡면 위 점·잠근 선과 끌어온 축의 교차·반투명 너머 고르기를 넣은 뒤 첫 화면 JS는 gzip 88.68 kB에서 88.99 kB(새 이름 가르기·반투명 보기 판정)이고,
광선 쪽 첫 근 고르기는 접선 조각에 들어가 접선 조각이 17.23 kB에서 17.93 kB, 코어 조각이 71.84 kB에서 76.72 kB가 되었습니다(해석 워커는 그대로).
그 뒤 휴대폰 성능 예산(88 KiB)을 넘지 않게 정밀 조준(뷰어를 만들 때 캔버스에 다는 것 — 코어 모듈과 함께)을 코어 조각으로 옮겨
첫 화면 JS는 gzip 88.99 kB에서 87.18 kB, 코어 조각은 76.72 kB에서 78.53 kB가 되었습니다(동작은 그대로).
개체 측정 계산(·와 최소 거리용 코어 · 모듈)도 뷰어의 누르기로만 쓰므로 코어 조각으로 옮겨
첫 화면 JS는 gzip 87.18 kB에서 78.97 kB, 코어 조각은 78.53 kB에서 86.56 kB가 되었습니다(동작·문구는 그대로 — 측정 띠·패널이 바로 쓰는 값 글만 첫 화면의 에).
코어 0.24.0과 측정 중 반투명 보기 전환을 넣은 뒤 첫 화면 JS는 gzip 78.97 kB에서 79.02 kB(전환 함수 몇 줄)이고, 코어 조각이 86.56 kB에서 88.07 kB가 되었습니다
(접선 조각은 17.93 kB 그대로). 코어 0.23.0과 견준 측정 붙잡기 화면 격자 118,800자리(장면 5개 × 잠금·끌어온 점 상태 9개)는 한 자리도 바뀌지 않았습니다.
CI의 휴대폰 검사가 재는 JS는 같은 빌드의 vite gzip 값보다 1.2 kB쯤 큽니다(CI의 압축 차이와 응답 머리).
서비스 워커는 이 조각들도 미리 담아 오프라인에서 엽니다.
공용 사이트 도구: 다섯 언어 페이지·검색 정보·사이트맵·내용 수정일·언어별 앱 정보·서비스 워커 빌드, 공용 번역기, 언어 메뉴, 서비스 워커 등록·새 판 알림,
방문 통계, 휴대폰 성능 비교 명령은 다른 OpenCAD 앱과 함께 쓰는 opencad-site-kit
(github:GyuTae-Kim/opencad-site-kit#v0.1.4, 잠금 커밋 a1de400, 빌드 때만 써서 devDependencies)에 있습니다.
이 앱에만 있는 값은 tools/site.mjs(앱 정보 원본, 서비스 워커 판 이름 짓기)와 tools/sw-source.mjs(서비스 워커 본문 — 돌려주는 글이 sw.js에 그대로 들어갑니다)에 둡니다.
check:seo·check:i18n·test:seo·update:content-dates와 휴대폰 성능 예산 검사는 도구의 opencad-site 명령입니다. 도구 판을 올릴 때는 빌드 결과를 견줍니다.
npx vite build && cp -R dist .runtime/dist-before # 올리기 전
npm install -D "opencad-site-kit@github:GyuTae-Kim/opencad-site-kit#<태그>" # package.json·잠금 파일을 함께
npx vite build && npx opencad-site compare-dist .runtime/dist-before dist # 바뀐 파일과 처음 다른 곳
도구의 판 설명에 적힌 것 밖의 차이가 없으면, 스크립트가 바뀐 경우 내용 수정일을 갱신하고 빌드·시험을 돌립니다.
로컬에 있는 STEP 파일을 앱과 같은 해석 길(parseStepFile — 압축 풀기, STEP인지 가리기, stepToScene)로 모두 열어 보고 결과를 모읍니다.
표본 파일은 저장소에 넣지 않으므로 각자 가진 폴더를 줍니다.
npm run sweep -- --dirs ~/cad:~/Downloads --out .runtime/sweep/before # 표본 폴더(쌍점으로 구분)
npm run sweep -- --dirs ~/cad:~/Downloads --out .runtime/sweep/after --quality normal,fine,finest
npm run sweep:compare -- .runtime/sweep/before .runtime/sweep/after # 바뀐 파일만 보기
.stp .step .p21 .stpz .stp.gz와, 안에 STEP이 든 .gz .zip만 고릅니다. 내용(sha256)이 같은 파일은 한 번만 엽니다.
숨은 폴더와 node_modules는 건너뜁니다.--dirs가 없으면 환경 변수 OPENCAD_SWEEP_DIRS를 보고, 둘 다 없으면 쓰는 법만 보이고 끝납니다(CI에서는 돌지 않습니다). --list로 파일 목록을 줄 수도 있습니다.--quality에는 앱의 곡면 품질 이름(normal fine finest)이나 각도(20 10 5 — 최대 각만 바꿉니다)를 쉼표로 여러 개 줍니다.
--jobs는 일꾼 수, --limit은 열 파일 수, --timeout은 파일 하나의 시간 한도(초)입니다.ms는 문서를 여는 시간(적분 빼고), propsMs는 그 뒤 적분 시간이고 요약에 둘 다 백분위로 남깁니다.x에는 해석 워커가 화면으로 넘기는 양(이전하는 버퍼 바이트 합), 모서리 표와 그 가운데 곡선 정의의 바이트, 끝 접선을 아는 곡선 모서리 수와
그 가운데 곡선 정의로 접선을 구하는 수를 적고, 요약에 합·백분위·최대로 남깁니다.
로컬 표본 2,085개에서 곡선 정의는 모서리 표를 27.8 MiB에서 32.4 MiB로(+17%), 전송량 합을 222.2 MiB에서 226.8 MiB로(+2.1%, 파일마다 p90 +2.6%, 최대 +24%) 늘렸고,
곡선 모서리 117,673개가 모두 정의로 접선을 구했습니다(B-스플라인 한도를 넘는 것 없음). 정의를 만드는 시간은 곡선 정의가 가장 큰 30개 파일에서도
문서 여는 시간의 0.2% 안입니다.
원호·타원 호에 틀 x축과 두 끝 매개변수 각(수 다섯, 40바이트)을 더 실은 뒤에는 로컬 표본 1,864개에서 곡선 정의가 2.34 MiB에서 4.67 MiB, 모서리 표가
25.70 MiB에서 28.02 MiB(+9.0%), 전송량 합이 188.19 MiB에서 190.51 MiB(+1.2%, 파일마다 중앙 +1.1%, p90 +2.8%, 최대 +4.0%·94 KiB)가 되었습니다.
한 바퀴 원은 끝이 없어 싣지 않습니다(실으면 전송량 합 +2.1%). 분류·예외·품질 지표·질량 속성 지문은 하나도 바뀌지 않았습니다..runtime/sweep/<날짜-시각>)에는 records.jsonl과 summary.json이 생깁니다. records.jsonl은 파일과 품질마다 한 줄이고 열쇠는 내용 해시입니다
(경로는 이 로컬 결과에만 적습니다). summary.json에는 경로 없이 분류별 개수, 판(AP)별 개수, 오류와 경고 코드, 시간 백분위, 품질 지표를 적습니다.
결과가 이미 있으면 --resume(이어서)이나 --force(새로)를 줍니다. 비교 기준으로 남길 결과는 --keep으로 표시합니다.sweep:compare는 구한 길별 입체 수와 값 지문도 견줘, 해석기를 고친 뒤 질량 속성이 한 비트라도 바뀐 파일을 보입니다.sweep:compare는 같은 해시와 품질끼리 짝지어 분류가 바뀐 파일, 새 예외, 지표가 바뀐 파일(위 20개)과 요약 값을 전후로 보입니다.
출력에는 해시 앞 12자만 나옵니다(--paths를 주면 로컬 경로도). --fail-on-change를 주면 바뀐 것이 있을 때 1로 끝납니다.끌어오기 요청마다 .github/workflows/mobile-validation.yml이 PR 바탕(기준)과 PR(후보)을 같은 CI에서 빌드합니다. 휴대폰 첫 화면을 Lighthouse로 세 번씩 재서
중앙값 표를 작업 요약에 남깁니다(압축해서 주는 미리 보기 서버와 표는 공용 도구의 opencad-site serve-performance·performance-summary —
기준 빌드 뒤 이 커밋으로 돌아와 npm ci를 다시 해 명령을 찾습니다).
후보 중앙값이 tools/performance-budget.json의 예산을 넘으면 실패합니다(공용 도구의 opencad-site check-performance-budget). 지금 예산은 성능 90 이상, 접근성과 SEO 100,
FCP 2초, LCP 2.2초, TBT 300ms, CLS 0.02, JS 88 KiB 이하입니다(코어를 나눠 받은 뒤 로컬 중앙값 82 KiB — 전에는 135 KiB). 예산을 바꿀 때는 그때 잰 중앙값을 같은 파일의 note에 적습니다.
이어서 playwright-cli로 휴대폰 화면(390×844, 손가락)에서 쓰는 흐름을 확인합니다(tools/mobile-browser-check.js, 판정은 tools/check-browser-result.mjs).
파일 고르기로 합성 표본(tools/mobile-sample.stp)을 열고, 최근 문서 다시 열기, 예제 열기, 두 번 눌러 거리 재기, 끌어다 놓기, ?open=과 ?sample,
없는 주소를 열 때의 알림까지 봅니다.
로컬에서는 npm run build 뒤 dist를 .runtime/performance/candidate(와 baseline)로 복사하고, Lighthouse와 playwright-cli를
npm install --prefix .runtime/mobile-audit --no-package-lock [email protected] @playwright/cli로 받아 워크플로의 "Compare cold mobile loads" 단계 명령을 그대로 돌립니다.
끝에 npx opencad-site check-performance-budget .runtime/performance로 예산을 봅니다.
main에 push하면 .github/workflows/deploy.yml이 typecheck → test → build를 거쳐 dist/를 gh-pages 가지에 올립니다
(GitHub Pages: https://gyutae-kim.github.io/opencad-step/). 빌드는 상대 경로(base: './')라 어느 하위 경로에서도 돕니다.
끌어오기 요청은 .github/workflows/ci.yml이 같은 확인을 돌리고, .github/workflows/mobile-validation.yml이 휴대폰 검사(위 개발 절)를 돌립니다.
setItemPickOpaque로 할 수 있지만, 흐리게 한 부품은 이미 고르기에서 빠지고 불투명도는 너머를 보려고 낮추는 것이라 쓰임이 확인될 때로 미뤘습니다)2dcad-viewer의 src/formats/step/에서 분리했습니다(커밋 d7c584a 기준, 처음 들어온 것은 PR #7).
2D 뷰어 안에서 STEP 파일을 3D 탭으로 열던 화면(제품 나무 패널, 리본, 웹 워커 — src/app/view3d/)은 이 저장소의 혼자 도는 앱(src/app/)으로
새로 짰습니다(제품 나무·워커 프로토콜·이전 목록 등은 그 커밋의 코드를 옮겨 다듬었습니다).
MIT. 의존성 earcut은 ISC입니다(THIRD_PARTY_NOTICES.md).
site/metadata.json을 공통 원본으로 삼아 Vite 플러그인이 제목·설명·canonical·Open Graph·Twitter Card·JSON-LD를 초기 HTML에 넣습니다. 같은 원본으로 앱의 공개 주소를 담은 sitemap.xml도 생성합니다. 공유 이미지는 각 앱의 public/og-opencad.jpg이며 앱 파일과 함께 배포합니다. robots.txt는 같은 호스트 루트(https://gyutae-kim.github.io/robots.txt)의 설정이 적용됩니다.
site/content-history.json에는 실제 콘텐츠 수정 시각과 지문을 저장합니다. 초기 HTML 본문·메타데이터·공유 이미지와 빌드된 앱/워커 JavaScript·CSS를 비교하므로 앱 기능이 바뀌면 날짜 갱신이 필요합니다. 수정일 자체와 소스 맵은 비교에서 제외합니다.
npm run update:content-dates -- --at YYYY-MM-DDTHH:mm:ssZ를 실행합니다.npm run build로 다시 빌드합니다. 변경되지 않은 콘텐츠는 기존 날짜를 유지하며, 날짜가 오래되었거나 잘못된 경우 SEO 검사가 실패해 배포를 막습니다.npm run test:seo와 기존 테스트를 실행하고 메타데이터·수정일 기록을 함께 커밋합니다.일반 빌드나 배포 시각으로 날짜를 자동 갱신하지 않습니다. sitemap.xml의 lastmod와 앱 구조화 데이터의 dateModified는 동일한 기록을 사용합니다. 배포 뒤에는 앱·사이트맵·공유 이미지의 실제 공개 응답을 확인하고, 포트폴리오 통합 사이트맵의 연결 날짜도 새 앱 사이트맵과 맞춥니다. 사이트맵 게시와 검색엔진의 실제 수집·색인 완료는 별도로 확인합니다.
한국어 기본 주소와 영어(/en/), 일본어(/ja/), 중국어 간체(/zh-CN/), 독일어(/de/) 페이지를 제공합니다. 각 언어의 소개 본문과 검색·공유 메타데이터를 빌드할 때 생성하며, hreflang과 사이트맵이 같은 페이지의 언어들을 연결합니다. site/locales/*.json에 한국어 원문과 번역을 저장하고, 브라우저는 선택한 언어의 사전만 내려받습니다. 방문 중 외부 번역 서비스는 호출하지 않습니다.
우측 상단 지구본 아이콘에서 언어를 선택합니다. 방향키로 이동하고 Escape나 바깥 클릭으로 닫을 수 있습니다. 언어 선택은 URL에 반영하며, 열린 문서나 편집 상태를 다시 만들지 않고 화면 문구·접근성 설명·오류·도움말을 갱신합니다. 명령 식별자·입력값·파일명·모델 이름·원본 도면의 문자는 번역하지 않습니다. 새 데이터 이름을 표시하는 요소에는 translate="no"를 지정하고, UI 문구의 {0} 같은 변수 자리를 변경하지 마세요. 여러 줄 메시지와 새 한국어 문구도 번역 사전에 추가해야 합니다. ·로 이은 문장은 짧은 변수 문구(예: 제품 번호 {0})가 뒤 조각까지 그대로 잡으면 조각마다 따로 옮깁니다(남는 한국어가 적은 쪽을 고름 — 잡은 이름은 여전히 그대로). 해석기 경고 안의 까닭 목록("삼각화하지 못한 면 3개 / 100개 (경계 고리 없음 2, 평면 삼각화 실패 1)")은 문장 틀의 자리 값이라 그대로 남으므로, 화면에서 까닭 조각을 따로 감싸 조각마다 사전으로 옮깁니다(src/app/warnparts.ts).
npm run test:i18n은 언어 전환과 문서 데이터 보존을, npm run check:i18n은 다섯 언어의 정적 소개·canonical·언어 링크·사전 변수·에셋 경로를 검사합니다. 번역이나 앱을 수정하면 기존 콘텐츠 수정일 갱신 절차를 따른 뒤 다시 빌드합니다. 자동 번역 초안의 주요 메뉴와 제품명은 교정했으며, 긴 기술 설명에는 추가 원어민 감수가 필요합니다.
setItemOpacity(id, a, { pickable: false })). 나무의 "모두 보이기"는 숨긴 것과 격리를 함께 풉니다.
**불투명도…**는 고른 부품을 100·75·50·25·10%로(반투명 차례에 그림), "불투명도 모두 되돌리기"로 되돌립니다.
불투명도를 낮춘 부품이 있거나 나머지 흐리게 중이면 3D 누르기·작업 메뉴·두 점 측정은 반투명한 부품을 지나 그 뒤 불투명한 부품의 면을 고릅니다
(코어 v0.23.0 throughTranslucent — 뒤에 불투명한 면이 없으면 예전처럼 반투명한 부품). 반투명하게 한 덮개 너머 안쪽 부품을 고르거나 재는 데 씁니다.
둘 다 아니면 예전처럼 앞 면을 고릅니다(파일이 정한 투명 색만 있는 문서도 그대로).
두 점 측정 중에 격리 띠의 "격리 풀기"·"모두 보이기"로 반투명 보기가 꺼지거나 불투명도로 다시 켜져도 찍은 점·Shift·화살표·잠금 단추 잠금·끌어온 점은 그대로이고
그 자리 미리 보기부터 반투명 너머 고르기만 바뀝니다(코어 v0.24.0 setMeasurePickThrough — 그 전에는 붙잡기 선택을 다시 주어 잠금과 끌어온 점이 풀렸습니다).
부품 색 구분은 파일 색 대신 같은 제품(이름·제품 번호)마다 한 색(골든 각 색상환)으로 칠해 회색 조립에서 부품 경계를 봅니다(setItemColor).
분해 보기는 3D 보기 위 가운데 막대의 슬라이더(0~100%)로 부품을 조립 가운데에서 바깥쪽으로 옮깁니다(setItemMatrix, 표현 PMI는 제자리). 막대의 방식 단추로
단계별(기본)과 한꺼번에를 고릅니다. 단계별은 Autodesk 뷰어의 계층 분해처럼 바깥 조립부터 한 단계씩 벌립니다: 슬라이더를 조립 깊이(단계 수)로 고르게 나눠,
첫 구간에는 맨 위 조립 바로 아래의 하위 조립·부품이(하위 조립은 통째로) 그 조립 가운데에서 멀어지고, 다음 구간에는 하위 조립마다 그 안의 하위 조립·부품이
그 하위 조립 가운데에서 멀어집니다. 막대에 지금 벌리는 단계("단계 2/3")를 보입니다. 자식이 하나뿐인 마디는 단계로 치지 않고, 한 단계의 이동은 100%에서
(자리 가운데 − 부모 가운데) × 1.5입니다. 한꺼번에는 예전처럼 부품 자리마다 조립 가운데에서 함께 벌리고(평평한 조립은 두 방식이 같음), 이동이 조상 이동의 합이라
100%에서는 두 방식이 같은 자리입니다. 분해 정도와 방식은 보기 링크(exp:60,step — 아래)에 담깁니다. 부품 자리 3,000개 합성 조립에서 계획(묶음 범위를 한 번 잼)과
슬라이더 한 번은 몇 ms이고, 계획은 장면·방식마다 한 번만 세웁니다(src/app/explode.ts — 방식 단추·단계 글 src/app/explodebar.ts와 함께 문서를 열 때 받음).
측정·면 고르기를 켜면 분해를 접습니다(제자리 형상으로 잽니다). 코어는 장면을 바꾸면 겉모습을 풀므로 곡면 품질을 바꿔 다시 삼각화해도 앱이 다시 겁니다.
휴대폰에서는 방식 단추를 둘째 줄에 두고, 손가락 기기에서 슬라이더·방식 단추·닫기가 38px 이상입니다.setPickEdges(true) → Pick3d.kind 'edge', 선분 번호 → 모서리 표)를 켜 모서리 가까이 누르면 그 B-rep 모서리를 강조하고
길이(곡선 적분, 정확), 원은 Ø·반지름·둘레, 원호는 R·호 각·호 길이, 타원은 두 반지름, 중심·축·시작/끝 점을 측정 띠·패널·상태 막대에 보입니다.area·perimeter·exact).setMeasureFormat).
두 점 측정은 꼭짓점·윤곽선 끝점 말고도 원·원호 중심과 모서리 가운데 점에 붙습니다(코어 v0.8.0 setMeasureSnap): 모서리 표가 아는
모든 원·원호·타원 중심을 세계 좌표(자리 변환·묶음 원점 반영)로 늘 후보로 주어 구멍 가운데 빈 곳에 커서를 두어도 중심에 붙고,
측정 중에는 윤곽선도 골라 누른 B-rep 모서리의 끝점·곡선 길이 가운데 점·중심을 더합니다(곡선 모서리에서 꺾은선 토막의 가운데 점은 쓰지 않음 — src/app/snap.ts).
곡선 길이 가운데 점은 모서리 표의 곡선 정의로 잰 곡선 위 점입니다: 원은 두 끝 각의 가운데, 타원·B-스플라인은 |C′|를 가우스–르장드르로 적분해
길이 절반 자리를 뉴턴법으로 풉니다(개체 측정의 가운데 점 붙잡기도 같은 점 — 곡선 계산 조각을 받기 전에는 꺾은선 길이로 잰 점).
두 끝 매개변수는 해석기가 꼭짓점을 곡선에 내려 구한 값을 모서리 표에 실어 넘기므로(원호·타원 호의 틀 x축과 두 끝 각) 화면용 float32 꼭짓점과 상관없이
정확합니다(중심 100 mm 둘레 반지름 7.3 mm 원호에서 각 가운데와 같은 점 — 그 전에는 꼭짓점 반올림만큼 6.6e-8 mm 비켰습니다).
코어 v0.9.0의 추론 붙잡기도 켭니다: 윤곽선·선 형상 두 선분이 3D에서 만나는 교차점(×), 첫 점을 찍은 뒤 커서 둘레 모서리로 내린 수직 발(⊥),
붙잡을 점이 없을 때 첫 점에서 X·Y·Z축 방향(축 색 안내선). 원 중심이 512개를 넘으면 코어가 점 색인(BVH)으로 찾아 큰 조립에서도 마우스 이동이 느려지지 않습니다
(로컬 큰 조립 — 그물 128개·원 중심 5,404개 — 에서 이동 한 번에 중앙 0.4 ms).
곡선 모서리(원·타원·B-스플라인)에서는 코어가 고른 수직 발과 붙잡지 않은 모서리 위 점을 화면용 꺾은선(현) 위가 아니라 B-rep 곡선 위로 옮겨 찍습니다
(코어 v0.14.0 setMeasureSnap({ refine }), src/app/curvesnap.ts). 수직 발은 첫 점에서 곡선으로 내린 정확한 발(곡선 위에서 (첫 점 − 발)·접선 = 0인 점 가운데
코어 발에 가장 가까운 것)이고, 모서리 위 점은 커서 광선에 가장 가까운 곡선 위 점입니다. 둘 다 코어가 고른 토막과 앞뒤 두 토막 안에서 찾습니다(꺾은선 꼭짓점은
곡선 위 점이라 꼭짓점마다 곡선 매개변수를 처음 쓸 때 한 번 구해 둡니다). 코어 가운데 점이 오면 그 토막 두 끝 매개변수의 가운데로 옮깁니다 — 원에서는 그 호의
길이 가운데와 같고, 길이를 적분하지 않아 마우스 이동마다 가볍습니다(STEP은 코어 가운데 점을 꺼 두어 지금은 오지 않습니다).
표식·찍은 점·거리·dx·dy·dz가 모두 그 점까지입니다: 시험 장면에서 B-스플라인 판 모퉁이에서 반지름 10 mm 원기둥 테두리로 내린 수직 발은 현 위 발(원에서 0.0185 mm 안쪽)이면
24.4720 mm, 원 위 발이면 24.4609 mm입니다. 직선 모서리·곡선 정의가 없는 모서리·선 형상과 면 위 점은 그대로이고, 다듬은 점이 코어 점에서 화면으로
붙잡기 거리(마우스 10화소, 손가락은 터치 허용 거리)를 넘으면 코어가 버리고 꺾은선 위 점을 씁니다. 붙잡지 않은 점을 곡선 위로 옮겼으면 이름은 "곡선 위 점"입니다.
코어 v0.15.0부터는 꺾은선으로는 후보가 없던 두 자리도 곡선 위로 붙습니다. 첫 점이 곡선에서 멀면 첫 점에서 꺾은선 토막에 내린 발이 모든 토막에서 토막 밖으로
떨어져 수직 발 후보가 없었는데, 코어가 커서 둘레 토막을 열린 후보(토막 끝)로 넘기면 같은 계산으로 곡선 위 발을 찾습니다 — 시험 장면에서 반지름 10 mm 원기둥 테두리(50토막)에서
50 mm 떨어진 판 꼭짓점에서 내린 발이 원 위 (10, 0, 20)이고 거리는 √2000 = 44.7214 mm입니다(가장 가까운 꺾은선 꼭짓점과는 0.2 mm 떨어진 자리).
교차점은 두 모서리 곡선의 3D 교차점으로 옮깁니다. 곧은 모서리는 두 끝 꼭짓점을 잇는 직선이고, 직선과 원·원과 원은 식으로(직선이 원 평면을 지나는 점,
같은 평면이면 이차식, 두 원 평면이 만나는 직선과 원), 타원·B-스플라인이 끼면 커서 둘레 표본에서 다른 곡선까지 거리가 가장 작은 곳에서 시작하는
두 매개변수 가우스–뉴턴법으로 풉니다. 두 곡선 위 점 사이가 허용치(두 토막 길이 합과 토막 끝 좌표 크기를 더한 값의 1e-6배)보다 멀면 3D로 만나지 않는 것이라
붙지 않고, 같은 모서리와 두 모서리가 함께 쓰는 꼭짓점(끝점 붙잡기가 맡습니다)도 넘깁니다. 두 곧은 모서리는 꺾은선이 곧 모서리라 코어 교차점 그대로입니다.
꺾은선끼리는 현의 처짐만큼 비켜 지나가 교차점이 없던 다른 평면의 두 곡선에도(코어의 넓힌 교차) 붙습니다 — 시험 장면에서 원기둥 테두리와 곧은 모서리·
세로 원·B-스플라인의 교차점이 모두 1e-9 mm 안입니다. 다듬은 점은 커서 광선·첫 점과 상관없이 두 토막으로만 정해져 코어가 기억해 다시 씁니다.
측정 중 커서 아래 붙잡을 점의 종류(꼭짓점·끝점·가운데 점·중심·교차점·수직 발·X축 방향·"X축 · 모서리 위"·"X축 · 면 위"·"잠근 X축 · 모서리 위"·끌어온 점에서 Z축·끌어온 Y축과 X축의 교차·모서리와 나란히·곡선 위 점·면 위 점)를 상태 막대와 측정 띠에 보이고(휴대폰은 정밀 조준 십자선을 끌 때),
찍은 결과의 종류("끝점 → 수직 발" 등)는 측정 띠·패널 아래 띠·상태 막대에 함께 보입니다. 축 방향의 축은 코어가 결과에 실은 값(v0.9.1 axisB)을 씁니다.
코어 v0.10.0의 모서리와 나란히(커서가 앞서 지나간 모서리와 첫 점에서 나란한 방향, 자홍 안내선)와 방향 잠금도 켭니다(SketchUp의 추론 잠금).
끝점을 잡는 동안 Shift를 누르고 있으면 지금 방향(축·모서리와 나란히·수직 발 쪽)을 잠그고 떼면 풉니다. 화살표 →·←·↑는 X·Y·Z축, ↓는 지금 방향을 잠그고
같은 키로 풉니다(패널·메뉴에 초점이 있으면 그쪽 키). 잠그면 첫 점을 지나는 그 선 위에만 찍고, 다른 꼭짓점을 가리키면 그 점을 선에 내린 자리를 찍습니다
(예: Z축 잠금 + 바닥 꼭짓점 = 첫 점 바로 아래, 결과 이름 "Z축 방향 · 잠금"). 첫 점이 모서리 끝이면 그 모서리를 따라 가리키지 않고 바로 다른 끝이나
B-rep 가운데 점 위에서 Shift를 눌러도 그 모서리 방향으로 잠급니다(벽 모서리 끝에서 높이를 잴 때 — 코어 v0.12.0이 커서 아래 점이 첫 점을 지나는 모서리 위인지 봅니다).
첫 점이 원·타원·B-스플라인 같은 곡선 모서리의 끝 꼭짓점이고 커서가 그 모서리 위(다른 끝·가운데 점·곡선을 그린 꺾은선의 꼭짓점)에 있으면
Shift·↓·잠금 단추는 그 끝에서의 접선 방향으로 잠급니다. 꺾은선 첫 토막의 방향이 아니라 해석기가 B-rep 곡선의 도함수로 구한 접선입니다
(반지름 10 mm 원기둥 테두리에서 첫 토막과 3.6° 차이). 방향은 늘 첫 점에서 커서가 있는 곡선 쪽으로 나갑니다: 첫 점이 모서리의 시작 꼭짓점이면 모서리 방향,
끝 꼭짓점이면 그 반대, 한 바퀴 원처럼 두 끝이 같은 꼭짓점이면 커서가 원을 그린 꺾은선 길이로 앞 절반에 있으면 원이 도는 쪽, 뒤 절반이면 거꾸로 도는 쪽입니다.
커서 아래가 축·모서리와 나란히·수직 발이면 그쪽이 먼저이고, 반원판의 지름처럼 첫 점에서 곡선의 다른 끝으로 곧은 모서리가 이어지면
그 끝에서는 그 모서리 방향입니다(코어 v0.12.0 모서리 끝 잠금 그대로 — 곡선 접선은 곡선 위 다른 점에서). 상태 막대·측정 띠·결과에는 "접선 방향"이라 적습니다(src/app/tangent.ts).
첫 점이 곡선 모서리의 끝이 아닌 곳(코어가 주는 모서리 위 점, 곡선 가운데 점, 곡선을 그린 꺾은선의 꼭짓점)이어도 커서가 같은 모서리 위에 있으면
Shift·↓·잠금 단추는 그 점에서의 접선으로 잠급니다. 첫 점에서 B-rep 곡선 위 가장 가까운 점을 찾아 그 자리의 접선 방향을 씁니다(곡선 위로 다듬은 첫 점이면 그 자리,
꺾은선 위 점이면 곡선에서 조금 안쪽이라 가장 가까운 곡선 위 점). 원은 식으로, 타원은 매개변수 각에서, B-스플라인은 매듭 구간을 나눈 표본에서 뉴턴법으로 찾습니다(src/edgecurve.ts).
곡선 위로 다듬은 첫 점·커서 아래 점은 꺾은선에서 현의 처짐만큼 비켜 있으므로, 꺾은선까지가 허용치 밖이어도 처짐 한도(그 모서리의 가장 긴 토막의 반) 안이면
곡선 정의로 잰 곡선까지 거리로 그 모서리 위인지 봅니다.
첫 점이 놓인 모서리와 커서 아래 점이 그 모서리 위인지는 코어 v0.16.0이 찍은 점·미리 보기에 싣는 선분 식별자(segment·교차점의 other)로 정합니다:
첫 점이 모서리 안쪽(모서리 위 점·수직 발·교차점·꺾은선 안쪽 꼭짓점)이면 그 모서리만 보고, 커서 아래 점의 토막이 그 모서리 것이면 거리를 재지 않고 그 위로 봅니다.
식별자는 꼭짓점을 함께 쓰는 모서리 가운데 하나만 가리키므로 첫 점이 모서리 끝(꼭짓점)이면 그 꼭짓점에 닿는 다른 곡선도 보려고 좌표로 찾고,
식별자가 없는 점(앱이 주는 곡선 가운데 점·그물 꼭짓점·축 위 점)도 좌표로 찾습니다(실제 코어 시험에서 식별자를 지운 상태와 접선이 비트까지 같습니다).
방향은 첫 점에서 커서가 있는 쪽입니다. 반지름 10 mm 원기둥 테두리의 30° 지점에서 코어가 잠그려는 토막(현) 방향과 2.4° 다릅니다.
곡선 정의를 싣지 않은 모서리(B-스플라인 정의가 한도를 넘거나 옛 결과)는 꺾은선 꼭짓점에서 어림한 접선을 씁니다(시험의 타원·B-스플라인에서 0.3° 안).
손가락 기기는 측정 띠의 잠금 단추로 잠그고 풉니다(정밀 조준 중 다른 손가락으로 눌러도 됩니다). 단추와 ↓는 커서 아래에 잠글 방향이 없으면 첫 점 뒤 마지막으로 본 방향을
잠그고(커서가 캔버스를 떠난 뒤에도), 본 방향도 없으면 맞추는 법을 알립니다. 잠그면 그 알림을 거둡니다.
상태 막대·측정 띠에 "X축으로 잠금"·"모서리와 나란히 잠금"·"접선 방향으로 잠금"을, 키보드 기기에는 끝점을 잡는 동안 커서 아래에 Shift로 잠글 방향이 있으면 "Shift·화살표로 방향 잠금",
없으면 "화살표로 축 잠금"을 보입니다.
마우스·펜 커서를 꼭짓점·끝점·중심 같은 점 위에 0.5초 머물면 그 점을 기억해(작은 십자, 최근 셋) 그 점을 지나는 X·Y·Z 축에도 붙습니다(코어 v0.16.0 끌어온 축 —
첫 점 전에도 되고, 첫 점 축 위에서 그 점과 나란한 자리가 먼저입니다). 이름은 "끌어온 점에서 Z축"이고 결과에도 그대로 적습니다. 손가락은 머무르지 않습니다 —
길게 누르기는 정밀 조준이 쓰므로 끌어올 점을 따로 주지 않고, 정밀 조준 중 십자선 미리 보기는 마우스처럼 머뭅니다. 둘째 점을 찍거나 측정을 지우면 잊습니다.
기억한 두 점의 서로 다른 축이 만나는 자리(두 모서리 끝에 차례로 머문 뒤 면 한가운데 등 — "끌어온 Y축과 X축의 교차")와 끌어온 축이 모서리와 만나는 자리
("끌어온 점에서 X축 · 모서리 위")에도 붙고(코어 v0.17.0), 결과에도 그 이름을 적습니다. 코어는 셋 다 축 붙잡기로 주므로 찍은 점의 trackOther·segment로 가릅니다.
모서리 위 자리의 선분 식별자는 v0.16.0과 같아 그 점을 첫 점으로 한 곡선 접선 잠금도 그 모서리를 식별자로 찾습니다.
첫 점을 찍은 뒤에는 첫 점의 X·Y·Z축이 커서 둘레 모서리와 만나는 자리("X축 · 모서리 위")와, 첫 점 축이나 끌어온 축이 커서 아래 면을 뚫는 자리
("X축 · 면 위", "끌어온 점에서 X축 · 면 위")에도 붙습니다(코어 v0.18.0 axisEdges·axisFaces). 첫 점 축 위 점이라 Shift로 그 축에 잠글 수 있고,
결과에도 그 이름을 적습니다(코어는 축 붙잡기로 주므로 찍은 점의 segment·face로 가릅니다).
모서리가 원·타원·B-스플라인이면 축과 꺾은선(현)의 교차가 아니라 축 직선과 B-rep 곡선의 교차로 옮겨 찍습니다(코어 refine의 'axisEdge').
곧은 모서리는 두 직선의 가장 가까운 두 점, 원·타원은 식(축이 곡선 평면을 지나는 점, 축이 평면 위면 이차식의 두 교점 가운데 코어 점에 가까운 것),
B-스플라인은 커서 둘레 표본에서 시작하는 가우스–뉴턴법으로 풀고, 허용치와 모서리 범위는 교차점과 같습니다.
축이 B-스플라인에 닿기만 하는 자리(접하는 곳)는 두 접선이 나란해 반복이 접점 앞에서 멈추므로, 곡선 접선이 축과 나란한 매개변수를 1차원 뉴턴법으로 따로 풀어
그 접점(축 위로 내린 발)에 찍습니다 — 축에서 허용치보다 멀면 붙지 않고, 접점이 모서리 밖이면 끝점으로 당기지 않습니다. 시험 장면에서 판 가장 바깥에 접하는 Y축은
접점에서 1e-11 mm 안(그 전에는 2.4e-7refineFace, src/app/facesnap.ts). 면 고르기에 쓰는
면 표(그물 삼각형 → B-rep 면)로 곡면을 찾고, 원기둥·원뿔·구는 면 표에 실린 식(반지름·반각·축·중심)으로 이차식을, 원환은 곡면까지 부호 거리의 뉴턴법을 풀어
코어 점에 가장 가까운 교점을 씁니다. B-스플라인·회전·밀기·띄운 곡면은 면 표에 식이 없습니다. 해석 워커가 해석하면서 그런 면의 곡면 정의를 다음 해석까지 들고 있다가
(질량 속성 적분이 끝나면 되짚기 첫 짐작 격자를 버린 꼴로 — 로컬 파일 8개에서 GC 뒤 힙 차이로 재면 문서마다 3src/facesurf.ts) 해석기와 같은 곡면 계산으로
(u, v, 직선 매개변수) 세 값의 뉴턴법을 풉니다. 곡면 계산이 든 곡면 조각(gzip 7.5 kB)은 그때만 받고, 첫 화면 JS에는 요청 몇 줄만 들어갑니다.
한 매개변수 줄이 한 점으로 모인 극점(돔 꼭대기·둥글림 끝) 둘레에서는 코어 점을 곡면에 되짚으면 극점으로 가 뉴턴법이 멈추므로, 코어 점에서 수렴하지 않으면
그 삼각형의 꼭짓점과 매개변수 격자에서 코어 점에 가까운 칸에서 다시 풉니다(코어 점에서 그 삼각형의 가장 긴 변 안인 교점만 — 먼 근은 받지 않습니다).
시험의 돔 꼭대기 둘레 480자리 가운데 다시 풀기 전 262자리가 삼각형 위 점이었고 지금은 모두 곡면 위 1e-9 mm 안입니다.
교점이 잘린 면의 경계 안인지도 봅니다. 해석기는 면을 매개변수 공간의 경계 다각형 안에서 삼각화하고 경계 꼭짓점을 모서리 위에 두므로, 그 면의 삼각형을 교점의 접평면에 펼쳐
교점이 어느 삼각형 안(허용치는 교점과 코어 점 사이의 두 배)인지 보고, 경계 밖이면 삼각형 위 점 그대로입니다. 평면 면은 삼각형 위 점이 곧 면 위 점이라 다듬지 않습니다.
시험 장면에서 판 꼭짓점의 X축이 반지름 10 mm 원기둥 옆면을 뚫는 점은 원기둥 위 1e-9 mm 안(다듬기 전에는 0.02 mm 안쪽)이고, 매단 판 꼭짓점의 Z축이
B-스플라인 지붕을 뚫는 점도 곡면 위 1e-9 mm 안입니다. 로컬 STEP 83개 파일의 곡면 4,837자리(면 가운데 삼각형의 무게중심을 지나 그 면에 가장 수직인 세계 축)에서
4,826자리를 곡면 위로 옮겼고, 옮긴 점에서 곡면까지 거리는 가장 커도 4.8e-11 mm였습니다(원기둥 2,396·원뿔 1,489·원환 623·B-스플라인 191·구 72·회전 47·밀기 8).
옮기지 않은 11자리는 얇은 띠 모양 원기둥 면의 비스듬한 삼각형에서 축이 곡면과 만나지 않은 6자리와, 작은 B-스플라인 면의 극점 둘레에서 축이 곡면에 거의 나란히
(곡면 법선과 cos 0.06lockEdges·lockFaces).
상태 막대·측정 띠·결과에는 "잠근 X축 · 모서리 위"·"잠근 X축 · 면 위"라 적습니다(축이 아닌 방향으로 잠갔으면 "잠근 방향 · 모서리 위", 곡선 접선 잠금이면 "잠근 접선 · 면 위" 꼴).
코어 결과에는 잠금만 실리므로 찍은 점의 segment·face로 가릅니다. 잠근 선에도 위의 곡선·곡면 다듬기가 그대로 쓰입니다 — 이음 꼭짓점에서 X축으로 잠그고
맞은편 테두리를 가리키면 원 위, 판 꼭짓점에서 X축으로 잠그고 원기둥 옆면을 가리키면 원기둥 위 1e-9 mm 안입니다. 코어 v0.20.0부터는 축이 아닌 방향(모서리와 나란히·수직·
곡선 접선·앱이 정한 방향)으로 잠근 선도 다듬어, 원 테두리와 만나는 점은 원 위, 원기둥 옆면·B-스플라인 곡면을 뚫는 점은 곡면 위 1e-9 mm 안입니다(그 전에는 꺾은선·삼각형 위 점).
잠그지 않았을 때는 두 선택을 켜도 끈 것과 값이 같고, 코어 v0.19.0과 v0.20.0을 견준 화면 격자 92,400자리(장면 5개 × 잠금 상태 7개)에서도
축이 아닌 잠근 선이 원기둥을 뚫는 한 자리(이제 곡면 위)만 달랐습니다.
잠근 동안 잠근 선이 끌어온 점(머물러 기억한 점)의 X·Y·Z축과 만나는 자리에도 붙습니다(코어 v0.21.0 lockTracks). 이름은 "잠근 X축 · 끌어온 점 Y축 위"이고,
세계 축으로 잠갔는데 끌어온 점의 축이 잠근 축과 만나지 않으면(끌어온 점이 첫 점과 함께 쓰는 좌표가 없으면) 잠근 축 위 끌어온 점과 나란한 자리
("잠근 X축 · 끌어온 점과 나란히")에 붙습니다. 결과에도 그대로 적습니다.
축이나 잠근 선이 곡면을 스치며 그물 삼각형은 비켜 가는 자리(구 실루엣 둘레, 볼록한 원기둥 벽을 비스듬히 스치는 축)도 코어 v0.22.0부터 같은 계산으로 곡면 위 교차에 붙습니다.
붙잡지 않은 면 위 점도 그 면이 곡면이면 커서 광선과 B-rep 곡면의 교점으로 옮겨 찍습니다(코어 v0.21.0 'onFace'). 이름은 "곡면 위 점"이고 결과에도 적습니다.
광선이 곡면을 두 번 뚫으면 광선 쪽 첫 근을 씁니다. 원기둥 실루엣 둘레를 스치는 커서는 맞은 삼각형 위 점이 두 근 사이라 나가는 근(뒤쪽 면)이 더 가까울 수 있는데,
그 자리 곡면 법선이 맞은 삼각형과 같은 쪽을 보는 근만 받습니다. 구멍 안쪽 벽처럼 오목하게 보이는 곡면에서는 맞은편 벽 위 근입니다.
면 경계 밖이면 삼각형 위 점 그대로이고, 평면은 다듬지 않습니다("면 위 점"). 시험 장면 원기둥 옆면 위 점은 반지름 10 mm에서 1e-9 mm 안(그 전에는 0.02 mm 안쪽)입니다.
B-스플라인 등의 곡면 정의를 워커에서 받으면 코어가 받기 전에 기억한 결과만 비워(clearMeasureRefine) 찍은 점·Shift 잠금·끌어온 점은 그대로 두고 지금 미리 보기부터 곡면 위로 옮깁니다.
코어 v0.20.0(앞 판)과 견준 화면 격자 118,800자리(장면 5개 × 상태 9개)에서 바뀐 29,155자리는 곡면 위 점 16,461자리, 곡면 위로 옮겨 찍은 첫 점에서 그은 축·잠근 선 위
점 12,687자리(원기둥 안쪽 꼭짓점을 겨눠 원기둥 옆면에 찍힌 첫 점이 0.023 mm 옮겨 갔습니다), 잠근 선과 끌어온 축의 교차 7자리뿐입니다.
곡면 위 점은 원기둥이면 모두 반지름 10에서 1.5e-13 mm 안·광선이 들어가는 근, B-스플라인 지붕이면 곡면에서 8e-15 mm 안이고 광선을 눈 쪽으로 되짚어도 앞에 다른 교점이 없습니다.
코어 v0.10.0의 붙잡기 점 차례 한도(SnapPoint.order·setMeasureSnapLimit)는 쓰지 않습니다 — 차례(재생 위치 같은 순서)가 있는 점을 거르는 기능이라
STEP에는 맞는 차례가 없고, 숨긴 부품의 중심은 코어가 점의 그물 id로 이미 빼며 큰 조립은 v0.9.0 점 색인으로 충분히 빠릅니다.
개체 측정은 면·모서리·꼭짓점 두 개를 눌러 잽니다: 모서리 끝점·가운데 점 가까이(마우스 9px, 터치 18px) 누르면 꼭짓점·가운데 점에 붙고, 원·원호 모서리는 중심으로 잽니다.
평면–평면은 나란하면 거리, 아니면 사이 각, 원기둥·원뿔 면(축)끼리는 나란하면 축 사이 거리(구멍 피치), 아니면 사이 각과 최단 거리,
원 중심–면·점–면·점–축·점–모서리·모서리끼리(나란하면 거리, 아니면 각과 최단 거리)를 B-rep 매개변수로 해석적으로 구합니다(src/app/entmeasure.ts).
B-스플라인 면·곡선 모서리처럼 해석적으로 못 재는 것이 끼면 고른 면 삼각형·모서리 선분 사이 최소 거리(≈, 코어 closestBetween)와,
다른 부품이면 부품 사이 최소 거리(≈, 코어 closestPoints)를 보입니다. 결과는 코어 덧그림(setAnnotations — 거리 선·각 호·원 중심 점, 값 글)으로 3D에 그리고
측정 띠·패널 아래 띠·상태 막대에 이름표와 값을, 측정 기록 CSV에 줄을 남깁니다. 셋째 개체를 누르면 새로 재고, Esc는 누른 개체를 지운 뒤 측정을 끝냅니다.
측정 중 단위·소수 자리를 바꾸면 덧그림 글도 바뀝니다. 문서를 바꾸면 덧그림을 지웁니다.setMeasureLabelAvoid) 첫 점 가까이를 조준해도 거리가 가리지 않습니다.
거리 글상자는 3D 보기 위에 떠 있는 측정 띠·분해·격리 띠·단면 막대·뷰 큐브도 비켜 그립니다(src/app/labelavoid.ts). 휴대폰에서 위쪽을 재면 글상자 오른쪽이
뷰 큐브 밑으로, 잰 뒤 보기를 옮겨 두 점 가운데가 측정 띠 높이에 오면 글상자가 띠 밑으로 들어가던 것입니다. 기본 자리(두 점 가운데의 오른쪽 위)가 이것들과
겹칠 때만 왼쪽 위·선분 위 다른 자리·띠 바로 위로 옮기므로, 겹치지 않는 측정은 넓은 화면·휴대폰 모두 그림이 그대로입니다. 띠가 나타나고 사라지거나 줄 수가 바뀔 때,
뷰 큐브를 끄고 켤 때, 화면을 돌릴 때 자리를 다시 알립니다. 잠깐 뜨는 알림은 비키지 않고, 그림 저장(PNG)에는 늘 기본 자리로 그립니다.
개체 측정의 3D 덧그림 글상자(거리·각 값)도 코어 v0.23.0부터 같은 자리를 비켜 그립니다 — 휴대폰에서 아래쪽을 재면 덧그림 글상자가 측정 띠에 걸리던 것입니다.
코어 v0.24.0부터는 덧그림 글상자끼리도 겹치면 뒤의 것이 비킵니다. B-스플라인 지붕처럼 해석적으로 못 재는 면을 다른 부품의 면과 재면 "최소 거리 ≈"와
"부품 사이 최소 거리 ≈"가 거의 같은 선분이라 두 글상자가 한 자리에 겹쳐 하나만 보이던 것입니다(이제 부품 사이 글상자가 옆으로). 겹치지 않는 덧그림은 자리가 그대로이고
그림 저장(PNG)은 기본 자리입니다. 뷰 큐브 자리는 코어가 알려 주는 사각형(viewCubeRect)을 씁니다.
손가락 기기의 안내에는 키(Esc) 설명 대신 길게 누르기를 적고, 파일 고르기 상자는 확장자로 거르지 않습니다(iOS에서 .stp가 흐리게 막히지 않게 — 열 때 내용을 보고 가립니다).
제목 막대 단추(열기·예제·설정·OpenCAD 도구·GitHub·언어)는 손가락 기기에서 40×40px이고, 폭 420px 이하 세로 화면에서는 앱 이름을 OpenCAD 아이콘과 "STEP 뷰어"로 줄여 한 줄을 지킵니다.
브라우저의 "홈 화면에 추가"로 앱 아이콘(public/manifest.webmanifest, 192·512px, 마스크용 512px, iOS 180px)과 주소창 없는 창으로 열 수 있습니다.
언어 페이지(/en/ 등)는 빌드가 만든 <언어>/manifest.webmanifest를 가리켜 그 언어 이름으로 설치되고 그 언어 페이지로 열립니다.
iOS 홈 화면 앱은 상태 막대를 화면 위에 겹쳐(black-translucent) 그리므로 제목 막대를 그 아래로 내리고, 흰 상태 막대 글씨가 보이게 그 띠는 테마와 상관없이 어둡게 칠합니다. 제목·상태 막대를 아래로 끌어도 당겨서 새로 고침이 일어나지 않아 연 모델을 잃지 않습니다(패널·시작 화면 목록은 그대로 스크롤).
오프라인: 빌드가 만든 서비스 워커(dist/sw.js — 본문 tools/sw-source.mjs, 목록·판 이름은 공용 사이트 도구)가 앱 껍데기(언어 페이지·앱 정보·아이콘)와 빌드 결과를 미리 담아,
신호 없는 현장에서도 홈 화면 앱이 열리고 최근 문서를 엽니다. HTML은 네트워크 먼저(배포가 바로 보이게, 안 되면 담아 둔 것), 미리 담은 파일과 빌드 결과(assets/)는 담아 둔 것 먼저이고,
그 밖(?open=으로 받는 STEP 파일 등)과 앱 범위 밖 주소는 서비스 워커가 손대지 않습니다(바뀐 파일이 옛것으로 열리거나 큰 파일이 쌓이지 않게).
새 판이 설치되면 "새 버전이 있습니다 · 새로 고침" 알림을 띄우고, 누르면 새 판으로 바꿔 다시 읽습니다(판 이름은 담는 파일들의 내용 지문).
공유 받기(Android): 앱 정보의 share_target(POST …/share-target)으로 메일·파일 앱의 "공유 → STEP 뷰어"를 받아, 서비스 워커가 파일을
최근 문서(IndexedDB)에 넣고 ?recent=<id>로 엽니다(60MB 넘으면 까닭을 알림). 데스크톱 파일 열기: file_handlers와 launchQueue로
설치한 앱을 .stp·.step·.p21·.stpz·.gz·.zip의 "연결 프로그램"으로 쓸 수 있습니다. 앱 정보에는 id를 두지 않습니다(언어 페이지마다 start_url이 id).src/worker/check.worker.ts)에서 찾습니다 —
범위 상자가 겹친 쌍만, 겹친 상자 안 삼각형을 격자로 나눠 서로의 평면 양쪽으로 걸치는 교차만 셉니다(맞닿은 면·모서리는 간섭이 아님).
삼각형마다의 범위 상자와 평면은 그물마다 한 번 구해 쌍 사이에 다시 쓰고 삼각형 쌍 시험은 새 배열을 만들지 않아, 로컬 큰 조립 다섯 개(그물 94props)에 자리 변환을 반영해 더합니다. "정확도" 줄에 어림 오차가 부피의 1e-9 밑인 입체는
"정확(B-rep 곡면 적분)", 모서리 곡선이 곡면에서 그보다 멀리 떨어졌거나 곡면 적분을 못 한 면이 섞였으면 "근삿값(±0.001% 미만)"처럼 부피 기준 어림 오차를 보이고, 그때는 값 앞에 ≈를 붙입니다.
면 표 질량 속성이 없으면(면 표를 끈 해석 등) 예전처럼 화면용 삼각형으로 잰 값이라 "근삿값(화면용 삼각형)"입니다. 겉넓이는 B-rep 면 넓이의 합, 외형 크기는 화면용 삼각형으로 잰 값(≈)입니다.
곡면 적분은 문서를 보인 뒤 해석 워커가 따로 합니다. 고른 입체의 값이 아직 없으면 부피·질량·무게중심·관성은 "계산 중…"이고 정확도 줄에 끝낸 입체 수를 보이며,
값이 오는 대로 그 묶음만 고칩니다. 다 끝나기 전에 다른 파일을 열면 적분을 그만두고, 그 파일을 열지 못해 이 문서로 남으면 남은 입체는 화면용 삼각형 값과 안내를 보입니다.
질량은 부품의 파일 밀도(없으면 고른 재질 — 강철·알루미늄·황동·ABS 등, 또는 g/cm³ 직접 입력)로 구하고, 무게중심은 질량을 알면 질량 가중입니다.
질량을 알면 관성 모멘트도 보입니다: 무게중심 기준 주 관성 모멘트 셋(작은 것부터)과 장면 축 Ixx·Iyy·Izz(크기에 따라 kg·m²·kg·mm²·g·mm²).
입체마다 기준점 기준 2차 모멘트를 자리 변환으로 세계로 옮긴 뒤 평행축 정리로 무게중심 기준으로 옮깁니다(주축은 야코비 회전 — src/app/physics.ts).
여러 개를 골랐으면(아래 "여러 개 고르기") 그 합입니다.toBlob({ scale, transparent, overlays })·snapshotSize), STL·OBJ(보이는 것 또는 고른 것 가운데 보이는 것 —
화면용 삼각형을 세계 좌표·장면 단위로, 거울 자리는 감기를 뒤집어 바깥 법선을 지킴), 측정 기록(이 문서에서 잰 거리·고른 면)·의미 PMI 표 CSV 복사
(화면 언어 머리 줄, 표시 단위, 엑셀용 BOM — 클립보드를 못 쓰면 파일로), 보기 링크 복사.
손가락 기기에서 파일 공유가 되면(navigator.canShare({files})) 그림·STL·OBJ를 공유 시트로 건네고, 아니면 내려받습니다.#view=cam:…;sec:…;sel:…;iso:1;exp:60,step — 카메라(대상·거리·방향·투영)·단면 평면·고른 것·격리·분해만 담고 파일은 담지 않습니다.
고른 것(sel)은 나무 자리 낱말을 쉼표로 잇습니다: 0/2/1(나무 마디 통째), 0/2.3(마디 0/2에 바로 놓인 셋째 형상 항목 — 입체 다음 선 형상 차례라
입체가 둘이면 첫 선 형상, 나무의 몸체 줄 하나), 0/2/4-9·0/2.1-3(이웃한 형제 마디·몸체를 줄여 씀). 마디 아래 형상을 모두 골랐으면 그 마디 하나로 묶고,
나무에 없는 항목(표현 PMI 선)은 담지 않습니다(src/app/selink.ts). 예전 링크의 sel:0/2/1(마디 하나)과 입체 몸체 낱말은 이 꼴의 한 경우라 그대로 열리고,
마디 하나만 고른 새 링크는 예전 앱에서도 열립니다(예전 앱은 선 형상 낱말만 빈 고르기로 건너뜀).
분해(exp)는 정도 1~100%와 방식(step 단계별 · all 한꺼번에)입니다. 링크를 열면 분해 막대를 열고 그 방식·정도로 벌리며, 분해가 없는 링크는 분해를 접습니다
(예전 앱은 모르는 열쇠라 건너뜁니다).
고른 것 글이 1,500자를 넘으면(흩어진 부품 수백 개 — 이웃한 것은 범위로 줄어 넘지 않음) 나무 차례로 앞의 것만 담고 "형상 N개 가운데 M개만 담았습니다"로 알립니다
(메신저·메일의 주소 길이 한도에 걸리지 않게 링크 전체를 2,000자 안쪽으로). 받는 쪽은 마디 하나면 그 마디를, 몸체 하나면 그 몸체를, 그 밖은 여러 개 고르기로 되살리고
몸체가 든 부품은 나무에서 펼치며, iso:1이면 격리합니다. 받는 사람이 같은 파일(또는 ?sample·같은 사이트 ?open=)을 열면 그 보기를 적용하고,
문서가 열린 뒤 해시가 바뀌면 바로 적용합니다(링크에 격리가 없으면 앞서 한 격리를 풉니다).opencad-step-display)에 기억합니다.
숫자는 화면 언어의 꼴로 씁니다(독일어는 소수점 쉼표, 좌표 구분 "; "). 파일에 길이 단위가 없으면 바꾸지 않습니다.
3D 보기 위 측정 글자(코어가 캔버스에 그림)와 개체 측정 덧그림 글도 같은 단위·자리 수·언어로 그립니다.
같은 대화 상자의 곡면 품질(보통·세밀 각 10°·아주 세밀 각 5°)을 바꾸면 연 파일을 다시 읽어 그 품질로 다시 삼각화하고,
카메라·단면·고른 것·숨김·격리·밀도·측정 기록은 이어 갑니다(해석 요청 options → stepToScene의 tolerance·angleTolerance).setScene(…, { incremental }))로 GPU에 프레임마다 나눠 올리고 상태 막대에 진행률을 보입니다
올릴 배열이 8 MB를 넘는 그물("아주 세밀" 품질의 큰 부품 등)은 코어(v0.9.0)가 4 MB씩 여러 프레임에 채웁니다.?sample은 예제를 바로 엽니다. ?open=<주소>는 같은 사이트의 파일만 엽니다(자동 확인용, 받는 동안 받은 양·진행률을 보입니다).
자동 확인용으로 window.opencadApp(state: 열린 문서 이름·해석 끝났는지·진행률·삼각형 수·고르기 단위·여러 개 고르기·고른 항목·고른 몸체·고른 면·고른 모서리·측정 종류·개체 측정·선/레이어/PMI 수·압축 형식·질량 속성 적분 상태 등, openSample(), openUrl(), cancel(),
selectProduct(), setTheme(), pickAt(x, y, face), setFaceMode(), setLayerVisible(), setPmiVisible(), setSection(axis, t))을 둡니다.src/app/partinfo.ts, src/app/physics.ts, src/app/viewhelp.ts, src/app/export.ts, src/app/viewlink.ts, src/app/selink.ts, src/app/interference.ts | 순수 로직: 부품 속성 줄·놓인 자리, 물리 속성(부피·겉넓이·무게중심·질량), 면 기준 보기·자르기·카메라 옮기기, STL·OBJ·CSV(문서를 열 때 받음), 보기 링크 글과 그 고른 것 ↔ 나무 자리 낱말(문서를 열 때 받음), 간섭 검사(교차·안에 듦) |
src/app/protocol.ts, src/app/client.ts, src/app/job.ts, src/app/glyphs.ts, src/worker/parse.worker.ts, src/worker/check.worker.ts | 해석 워커 메시지·이전 목록·삼각화 선택, 워커 손님(취소), 해석 일(압축 풀기 → 해석), 내장 글꼴에 없는 PMI 글자를 기기 글꼴 윤곽선으로(워커의 OffscreenCanvas), 해석 워커, 검사(간섭) 워커 |
src/app/warnparts.ts | 해석기 경고 한 줄 → 화면 조각(까닭 목록을 떼어 다국어 층이 조각마다 옮기게) |
src/app/stepText.ts, src/app/sample.ts | 작은 STEP 글쓴이(시험도 씀)와 예제 조립 모형 |
src/index.ts, src/messages.ts | 해석기 공개 입구, 해석기와 앱이 함께 쓰는 짧은 글(의존 없음 — 끊긴 파일 경고) |
src/archive.ts | 압축 STEP 풀기(gzip·ZIP), STEP-XML 알아보기 |
src/part21.ts | ISO 10303-21 글 해석 |
src/scene.ts, src/styles.ts, src/units.ts, src/layers.ts | 제품·조립·색·단위·레이어 → Scene3d |
src/wire.ts, src/pmi.ts, src/pmitext.ts, src/strokefont.ts, src/glyphtrace.ts, src/savedviews.ts | 와이어프레임·곡선·PMI 그림 → 선분, PMI 찾기와 의미 PMI 읽기(면 연결), PMI 글자 → 내장 획 글꼴 선분(없는 글자는 받은 모양), 글자 그림 알파 값 → 윤곽선(행진 사각형), 저장된 보기 |
src/props.ts | 제품 속성(설명·판·재질·밀도·사용자 속성) |
src/brep.ts, src/geometry.ts, src/curves.ts, src/surfaces.ts, src/nurbs.ts | B-rep 위상과 곡선·곡면 |
src/facesurf.ts | 면 표에 식이 없는 곡면(B-스플라인·회전·밀기·띄운 곡면) 정의를 해석 워커에서 화면으로 보내고 클래스를 다시 붙여 되살리기(측정의 축이 곡면을 뚫는 점 — 화면 쪽은 따로 받는 곡면 조각) |
src/edgecurve.ts | 모서리 표 곡선 정의(원호·타원 호의 틀 축과 두 끝 각, B-스플라인 기록) 만들기·읽기와 곡선 위 가장 가까운 매개변수·점·접선, 근 찾기, 곡선 길이 가운데(DOM 없음 — 해석기와 앱이 함께 씀) |
src/tessellate.ts, src/math.ts | 삼각화(해석적 곡면은 매개변수 영역 넓이 적분도) |
src/massprops.ts, src/propsjob.ts | 닫힌 입체의 질량 속성: 곡면 매개변수 공간의 가우스–그린 경계 적분, 삼각형으로 재는 면의 띠 메우기, 삼각화와 떼어 나중에 나눠 적분하기 |
src/analysis.ts | 틈·넓이·부피 검사, 닫힌 껍질 면 방향 맞추기(orientFaces) |
scripts/sweep/ | 실제 파일 훑기(npm run sweep)와 결과 비교(npm run sweep:compare) — 고르기와 중복 빼기, vite-node 일꾼, 분류 코드, 품질 지표, 요약 |
tools/mobile-browser-check.js, tools/performance-budget.json, tools/mobile-sample.stp | 휴대폰 검사 워크플로의 사용 흐름 확인, 성능 예산(확인은 공용 도구의 opencad-site check-performance-budget), 합성 표본 |
tests/app/locktrack.test.tstests/app/looks.test.tstests/app/annolabel.test.tstests/massprops.test.tstests/zipText.ts.runtime/github:GyuTae-Kim/opencad-viewer3d#v0.24.0npm install "opencad-viewer3d@github:GyuTae-Kim/opencad-viewer3d#v0.24.0"npm installMesh3d.triangleEdges: falsenpx vite --forceopencad-viewer3dsrc/app/core.tsimport()src/app/aim.tssrc/app/entpick.tssrc/app/viewerkit.tscameraviewcubeboundstests/app/core-split.test.tsVIEW_KEYScamerasrc/app/selink.tssrc/app/export.tsimport()src/app/tangent.tscore.tsimport()src/edgecurve.tssrc/app/curvesnap.tsrefinesrc/app/explode.tssrc/app/explodebar.tsimport()expsrc/app/facesnap.tssrc/facesurf.tssurfaces.tscurves.tsimport()pointersrc/app/entpick.tssrc/app/entmeasure.tsbvhclosestsrc/app/measure.ts