41 Commits

Author SHA1 Message Date
minsung
e1821c88cf rustdoc 경고 0개로 정리 — 단위 표기 false positive 완화
cargo doc --workspace --no-deps 에서 55 → 0 warnings.

## 변경
- crates/{ir, kernel, incremental, viewer}/src/lib.rs 최상단에
  #![allow(rustdoc::broken_intra_doc_links)] 추가.
  · 이유: doc comment 내 단위 표기 [mm] [m] [deg] [rad] [radians] 가
    intra-doc link 문법과 충돌 (40+ 건). 실제 intra-doc link 가 아님.
  · 각 crate 에 주석으로 이유 명시.
- crates/ifc/src/bridge_export.rs: camber_mid_mm doc comment 의 \[mm\] escape.
- crates/dsl/src/{cross_beam,expansion_joint}.rs: station doc comment \[m\] escape.
- crates/viewer/src/camera.rs: radius/yaw/pitch doc \[mm\]/\[radians\] escape.
- crates/incremental/src/lib.rs: `HashSet<FeatureId>` → backtick 래핑
  (unclosed HTML tag 경고 해소).

cargo check --workspace --all-targets: 0 warnings.
테스트 회귀 없음: cimery-ifc 20 + cimery-viewer 13 passed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 08:53:05 +09:00
minsung
8bcf65402c incremental_scene.rs — Sprint 8 scaffold 문서 갱신
역사 설명 + "현재 미사용" 명시:
- Sprint 8 PoC, Sprint 15 에서 IncrementalDb 5종 확장.
- Sprint 15+ 이후 lib.rs::rebuild_mesh() 가 IncrementalDb 직접 사용.
- 본 파일은 레퍼런스 예시로만 보존 (외부 참조 없음).

내부 TODO 주석 제거 (Sprint 9 는 이미 완료).

코드베이스 전체 TODO/FIXME 0건.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 08:47:14 +09:00
minsung
2361f318d4 cimery 루트 README + .gitattributes (LF/CRLF 경고 제거)
## .gitattributes
- * text=auto eol=lf → Rust 소스·설정파일 LF 통일.
- .png/.jpg/.ico/.usd binary 마킹.
- .bat/.cmd/.ps1 Windows 스크립트는 CRLF 유지.
- 매 커밋마다 뜨던 "LF will be replaced by CRLF" 경고 해소.

## cimery/README.md 신설
- Sprint 39 현재 상태 요약표 (기하/부재/UI/저장/IFC/배포/증분/테스트).
- 빌드 & 실행 예시 (check/test/run/tauri build/insta update).
- 크레이트 구조 트리 (11 crates) + 의존 방향.
- 참조 문서 링크 (dev-guide·ADR·ParaWiki·PROGRESS·PLAN).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 08:44:30 +09:00
minsung
6a80aac30b cimery-ifc README + usd 테스트 unused import 정리
## crates/ifc/README.md 신설
- Phase 1~3c 현황표 (Sprint 33~37) + 미구현 로드맵
- 사용 예: 직접 구성 / viewer scene_params_to_ifc 변환
- IFC 뷰어 호환성 (BlenderBIM/Solibri/Navisworks/IfcOpenShell)
- GUID 설명, snapshot 테스트 가이드

## crates/usd/src/lib.rs
cargo fix 로 unused imports 자동 정리 (test 모듈).

cargo check --workspace --all-targets --features occt: 0 경고.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 08:43:41 +09:00
minsung
a985e62254 문서 갱신 — dev-guide·cimery/CLAUDE.md·wiki log Sprint 39 반영
All checks were successful
Publish ParaWiki / build-and-deploy (push) Successful in 30s
## Output/guides/cimery-dev-guide.md
- related-adr 에 ADR-004 추가, updated 2026-04-15.
- 권위 순서: ADR-004 삽입.
- 아키텍처 파이프라인 다이어그램: salsa(Sprint 24), USD(21), IFC4X3(33~36)
  구현 스프린트 표기.
- Feature 카탈로그 실제 구현 현황 반영:
  Must v1: 다경간·PSC-I/SteelBox·T형/π형 피어 전부 완료.
  Should v1.1: Diaphragm·Haunch·Skew·Camber·Variable Depth 구현 완료.
- 구현 우선순위: "수직 관통 완료" 현황 추가.

## cimery/CLAUDE.md
- 크레이트 구조 Sprint 39 현황으로 재작성:
  · ifc/ 신규 (Sprint 33~36)
  · macros/ 신규 (Sprint 38)
  · app/ (Sprint 23)
  · 의존 방향 업데이트: core → ir → {dsl, kernel, usd, ifc}
- 업그레이드 경로 표: 5개 축(incremental/kernel/viewer/dsl/ifc) 의
  현재·다음 단계 표.
- 참조 ADR 목록에 ADR-004 추가.

## wiki/log.md
- ADR-004 entry 추가 (2026-04-15).

PROGRESS.md 는 이전 커밋에서 반영 완료.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 08:39:28 +09:00
minsung
e32c09df2d 품질 강화 — ADR-004 + IFC snapshot 테스트 + helper 유닛 + clippy 경고 정리
## ADR-004 (Output/reports/ADR-004-sprint-25-39-decisions.md)
Sprint 25~39 기간의 **15개 아키텍처 결정** 정리:
- D1~D9: 거더교 MVP 확장 (단면 분기·다경간·Skew 관례·방호벽·격벽·Camber·헌치·UI)
- D10~D13: IFC4X3 Add2 익스포터 4 결정 (크레이트 분리·형상 전략 3단계·GUID·Camber 근사)
- D14: proc-macro 스캐폴딩 (전면 #[param] 는 Feature 10+ 안정 후)
- D15: 변단면 거더 알고리즘 (소핏 lift + Y 선형보간)
- 미결 6항목 (Pset 확장·LinearPlacement·ElementAssembly·IfcPile·#[param] 전면·변단면 IFC)
- 테스트 커버리지 101개 현황표

## IFC 스냅샷 테스트 (crates/ifc/tests/snapshot_tests.rs)
insta 기반 회귀 방지, 8개 baseline:
- mask_guids(): 22자 IFC GUID 를 'GUID' 로 정규화 (결정적 비교 가능)
- 시나리오: 기본 단경간 PSC-I / 2경간 π형 / skew 15° / camber 50mm /
  Rectangle 단면 / parapets off
- mask_guids 자체 유닛 테스트 2개

## Mesh helper 유닛 테스트 (crates/viewer/src/bridge_scene.rs helper_tests)
순수 함수 9개 검증:
- apply_camber_mesh: zero 항등·midspan 도달값·경간 밖 미영향
- rotate_y_around_z: 0 회전 항등·90° 피봇 회전·정점 개수 보존
- apply_variable_depth: zero 항등·소핏 lift · 지점 0 lift

## clippy lib 경고 15+ → 0
- map_identity (kernel/expansion_joint.rs)
- unnecessary_lazy_evaluations ×4 (dsl/abutment·pier·csv_template — auto-fix)
- too_many_arguments (usd save_scene — allow with justification)
- clamp-like 패턴 ×7 (viewer bridge_scene/incremental_scene 의 .max(1).min(N) → .clamp(1, N))
- redundant_closure ×2 (project_file 의 `|e| Error::other(e)` → `Error::other`)
- redundant_guard ×1 (viewer KeyboardInput match guard → 패턴 내 직접 매치)

cargo clippy --workspace --lib: 0 경고.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 08:37:11 +09:00
minsung
0e4701de79 Sprint 36~39 — IFC Alignment/Camber + proc-macro 스캐폴딩 + 변단면 거더
## Sprint 36: IfcAlignment (IFC Phase 3b)
- write_straight_alignment(): 직선 horizontal(.LINE.) + 평지
  vertical(.CONSTANTGRADIENT.) 세그먼트 + IfcRelNests 계층.
- IfcAlignmentSegment × IfcAlignmentHorizontalSegment × IfcAlignmentVerticalSegment.
- Site aggregate 에 Bridge 와 Alignment 동시 포함.

## Sprint 37: IFC 거더 Camber 반영
- BridgeExportParams.camber_mid_mm 추가.
- camber > 0 일 때: 거더 1 개를 CAMBER_SEGMENTS(10) 세그먼트로 분할, 각 세그먼트
  Y 에 포물선 값 적용 → 곡선 거더 근사. Pset 는 첫 세그먼트에 한 번만 부착.
- viewer scene_params_to_ifc() 에서 camber_mid_mm 매핑.

## Sprint 38: cimery-macros 크레이트 (proc-macro 스캐폴딩)
- 신규 크레이트, proc-macro = true, deps: syn/quote/proc-macro2.
- #[derive(ParamSummary)] 구현:
  · 구조체 named field 의 PARAM_COUNT (usize) + PARAM_NAMES (&[&str]) 생성.
  · 선언 순서 보존, 빈 구조체 지원, tuple/enum 은 컴파일 에러.
- 테스트 3개 (tests/derive_test.rs).
- ADR-002 D 로드맵: #[param(unit, range, default)] 전면 attribute 는 후속.

## Sprint 39: 변단면 거더 (Variable Depth)
- SceneParams.variable_depth_mm (0~800mm) 추가.
- apply_variable_depth(mesh, z0, z1, max, girder_h):
  · lift(u) = 4·max·u·(span-u)/span²  (중앙에서 최대)
  · y_new = y + lift(u)·(1 - y/h)
  · 상면 y=h 는 고정, 소핏 y=0 을 최대 lift 만큼 올림. 연속교 중앙부
    web 축소 관례와 정합. camber 와 독립 조합 가능.
- build_bridge_scene / build_selectable_scene 거더 생성 루프에 각각 적용
  (거더 local 좌표계에서 먼저 → translate → camber 순).
- UI "변단면 (mm)" 슬라이더 (선형·기하 섹션).
- ProjectFile variable_depth_mm 필드 (default 0).

모든 테스트 통과: kernel 18 + ifc 20 + macros 3.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 19:48:07 +09:00
minsung
693c95dc6f Sprint 35 — 뷰어 IFC 익스포트 연결 + Pset_BeamCommon
## 뷰어 통합
- `cimery-viewer` → `cimery-ifc` 의존성 추가.
- `project_file::scene_params_to_ifc()` 변환 함수:
  SceneParams 의 모든 파라미터(경간 수·교각 형식·skew·헌치·단면 종류·신축이음)
  를 BridgeExportParams 로 전부 매핑.
- egui 프로젝트 섹션에 "📤 IFC4X3 익스포트" 버튼.
  현재 파라미터 상태로 즉시 `projects/bridge.ifc` 생성.
- `project_file::default_ifc_path()` 헬퍼.

## Pset_BeamCommon (IFC Phase 3a)
- `write_pset_beam_common()`: 4개 속성
  · Reference (IFCIDENTIFIER) — 거더 라벨
  · Span (IFCLENGTHMEASURE) — mm
  · LoadBearing (IFCBOOLEAN) — .T.
  · IsExternal (IFCBOOLEAN) — .F.
- IFCRELDEFINESBYPROPERTIES 로 각 IFCBEAM 에 연결.
- `IfcSectionKind` public re-export (viewer 에서 직접 참조).

## 테스트
- pset_beam_common_attached_to_girders 추가. 17개 전체 통과.
- cargo check --workspace --features occt: 0 errors.

Phase 3 남은 로드맵:
- IfcAlignment + IfcLinearPlacement
- Camber 반영 (현재 직선 girder 만)
- Pset_BearingCommon, Pset_SlabCommon
- IfcElementAssembly 로 Pier(column+capbeam) 그룹화

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 19:31:36 +09:00
minsung
567345e933 Sprint 34 — IFC4X3 Add2 익스포터 Phase 2
Phase 1(사각 profile·월드 원점) → Phase 2(정확 단면·skew·헌치·방호벽).

## 변경
### bridge_export.rs
- `IfcSectionKind` enum: PscI / SteelBox / Rectangle.
- `BridgeExportParams` 확장:
  · section_kind, skew_deg, haunch_depth, show_parapets, show_joints.
- `write_psc_i_profile()` 신설:
  · PSC-I 14점(top/bottom flange + web + haunch) 을
    `IFCARBITRARYCLOSEDPROFILEDEF` + `IFCPOLYLINE` 으로 출력.
  · 도심 중심화 (Y 를 h/2 만큼 아래로 평행이동) → beam 중심 배치와 정합.
  · start==end 점 복제로 profile close.
- `write_girder_profile()`: section_kind 따라 PSC-I / Rectangle 분기.
- `write_local_placement_skewed()`:
  · IFCAXIS2PLACEMENT3D RefDirection = (cos θ, 0, -sin θ) 로 Y축 회전 반영.
  · 교대·피어·받침에 적용. 거더·데크는 직선 유지(precast 관례).
- 헌치: deck Y = bearing_h + girder_h + haunch_depth + slab/2.
- 방호벽: IFCRAILING .GUARDRAIL. 좌/우 2개 (500×1200 × total_mm).

### 테스트
- psc_i_profile_is_used_by_default
- parapets_present_by_default / parapets_hidden_when_disabled
- rectangle_section_skips_psc_i
- skew_rotates_ref_direction (30° → cos30≈0.866 검증)
- haunch_moves_deck_up

16개 전체 통과.

Phase 3 로드맵(후속):
- IfcAlignment + IfcLinearPlacement (선형 기반 좌표)
- Camber 반영 (solid 변형 또는 여러 extrude 단면)
- Pset_BeamCommon·Pset_BearingCommon (Property Set)
- IfcElementAssembly 로 신축이음·격벽·피어(column+capbeam) 그룹화

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 17:58:23 +09:00
minsung
7f14423bcd Sprint 33 — IFC4X3 Add2 익스포터 Phase 1 (cimery-ifc 신설)
P2 로드맵 (Gitea #4) 첫 단계. 교량·토목 현재 표준인 IFC4X3 Add2 로 익스포트.

## cimery-ifc 크레이트 구성
- src/guid.rs: IfcGloballyUniqueId 생성.
  UUIDv4 128비트 → buildingSMART base64 22자 인코딩.
- src/writer.rs: STEP Part21 텍스트 writer.
  IfcWriter(alloc/emit/write/finish), Ref(#N), lit, real, real3, ref_list.
  HEADER 블록(FILE_DESCRIPTION/FILE_NAME/FILE_SCHEMA='IFC4X3_ADD2') + DATA 블록.
- src/bridge_export.rs: 교량 하이레벨 API.
  BridgeExportParams(span·girder·slab·bearing 치수) + export_bridge() -> String.

## 생성 엔티티 (Phase 1)
계층:
  IfcProject
    └ IfcRelAggregates → IfcSite
        └ IfcRelAggregates → IfcBridge
            └ IfcRelContainedInSpatialStructure → elements[]

원소:
- IFCBEAM × (span_count × girder_count) — 거더
- IFCSLAB × 1 — 데크 슬래브 (전 구간 연속)
- IFCCOLUMN × (span_count-1) — 피어 기둥 (내부 지점만)
- IFCFOOTING × 2 — 교대 (양 끝)
- IFCBEARING × (span_count+1)×girder_count — IFC4X3 신규 엔티티

형상 단순화(Phase 1):
- IFCEXTRUDEDAREASOLID + IFCRECTANGLEPROFILEDEF 일률.
- Phase 2 에서 IFCARBITRARYCLOSEDPROFILEDEF 로 PSC-I 14점 단면 매핑 예정.

단위: IFCSIUNIT mm (+ radian·squareMetre·cubicMetre·second·kilogram).
배치: IfcLocalPlacement 월드 원점 기준 (선형·skew·camber 는 Phase 2).

## 테스트
10개 통과:
- guid: 22자 고정, 동일 UUID 동일 GUID, 문자셋 유효성.
- writer: shell 구조, REAL 포맷, ref_list 포맷.
- bridge_export: 단경간 핵심 엔티티 포함, 다경간 피어 개수, 거더 수 일치, STEP 구조.

## 통합
- workspace Cargo.toml: crates/ifc 추가.
- cimery-app: export_ifc_default IPC 커맨드 (tauri dialog .ifc save).
- main.rs invoke_handler 등록.

Phase 2 로드맵(후속 스프린트):
- IfcAlignment + IfcLinearPlacement (선형 좌표)
- 실제 단면 profile (PSC-I · SteelBox)
- Pset_BeamCommon·Pset_BearingCommon
- IfcPile·IfcExpansionJoint·IfcKerb(방호벽)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 17:02:51 +09:00
minsung
94ce89093f Sprint 31/32 — 헌치 + 속성 패널 카테고리 재정리
Sprint 31: Haunch (데크 헌치).
- SceneParams.haunch_depth (0~300mm, step 10mm).
- 거더 상부와 데크 soffit 사이 600mm×haunch_d×span 블록을 경간별·거더별
  자동 배치. COL_DECK 로 색상 통일.
- 데크 위치: girder_h + slab_thickness → girder_h + haunch_depth + slab_thickness.
  6군데(build_bridge_scene + build_selectable_scene 의 데크·신축이음·방호벽)
  일괄 수정.
- camber + skew 동시 적용.
- UI: "헌치 (mm)" 슬라이더.

Sprint 32: 속성 패널 재정리.
- 누적 11개 슬라이더가 한 섹션에 섞여 혼잡 → 5개 CollapsingHeader 분리:
  · 상부구조 (경간·거더 관련 5항목)
  · 바닥판 (슬래브·헌치)
  · 선형·기하 (경사각·솟음)
  · 하부구조 (교각 형식)
  · 추가 부재 (가로보·신축이음·격벽 — 기존 유지)
  · 표시 (선형·투영 — 기존 유지)
- ps!($ui, ...) 매크로 hygiene 수정: ui 명시적 매개변수화로 macro_rules
  기본 hygiene 의 외부 캡처 문제 회피.
- "경간" 라벨 중복(span_m vs span_count) 해소: "경간 길이"/"경간 수".

ProjectFile: haunch_depth 필드 추가 (default 0.0).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 15:19:00 +09:00
minsung
0013182835 Sprint 29/30 — 지점부 격벽 + 거더 솟음
Sprint 29: Diaphragm (지점부 격벽).
- SceneParams.show_diaphragms 토글 (default true).
- 모든 지점(교대+교각) 에서 인접 거더 사이 RC 벽 배치:
  · 두께(span 방향): 300mm
  · 높이: girder_h (거더 soffit ~ top)
  · 폭: spacing - 250mm (web clearance 양쪽 125mm)
  · 지점 Z 기준 중앙 배치, skew 회전 동시 적용
- build_bridge_scene + build_selectable_scene 양쪽 구현.
- COL_DIAPHRAGM 색상 추가 (concrete 계열).
- UI: "격벽 (Diaphragm)" 체크박스.

Sprint 30: Camber (거더 솟음).
- SceneParams.camber_mid_mm (0~200mm, step 5mm) 추가.
- apply_camber_mesh(mesh, z0, z1, mid_mm) 헬퍼:
  u = z - z0 ∈ [0, span], y_off = 4·mid·u·(span-u)/span² (포물선).
  지점(u=0 또는 u=span) 에서는 0, 중앙 u=span/2 에서 최대 mid.
- 거더·데크에 경간마다 독립 적용. 다경간 교량도 경간별 정확한 solog.
- UI: "솟음 (mm)" 슬라이더.

ProjectFile: show_diaphragms + camber_mid_mm 필드 (default 값으로 v2 호환).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 14:01:58 +09:00
minsung
471fac53b3 Sprint 27/28 — Skew + 방호벽 + 관련 메타 갱신
Sprint 27: 경사각(Skew) 지원.
- SceneParams.skew_deg (-30°~30°) 추가.
- rotate_y_around_z(mesh, rad, pivot_z) 헬퍼: Y축 중심, 임의 Z pivot 회전.
  정점·법선 동시 회전.
- 적용 대상: 교대·교각·받침·신축이음 (각 지점 pivot_z 기준).
- 거더·데크는 직선 유지 (precast 거더 스큐 교량의 일반 관례).
- UI: "경사각(°)" 슬라이더.

Sprint 28: 방호벽(Parapet) MVP.
- 데크 양 엣지(half_w, -half_w) 에 1200mm×500mm RC 박스 전 구간 연속 배치.
- Y 기준: 데크 상면 (girder_h + slab_thickness).
- 색: COL_ABUTMENT 재사용 (콘크리트 브라운).
- build_bridge_scene / build_selectable_scene 양쪽 추가.
  선택 가능 씬에서는 "방호벽 (좌/우)" 라벨.

ProjectFile v2: skew_deg 필드 (default 0.0).
PROGRESS.md: Sprint 25~28 정리.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 12:42:21 +09:00
minsung
b37a50c90c Sprint 25/26 — 단면 분기 수정 + 다경간 + 피어 배치
Sprint 25: build_selectable_scene 의 SectionType::PscI 하드코딩 제거.
- p.section_type 에 따라 PscI / SteelBox 분기 (build_bridge_scene 과 동일 로직).
- 사용자가 단면 형식 전환 시 정상 반영.

Sprint 26: 다경간 + 교각 배치 (ParaWiki 교각 wiki Phase 1 MVP).
- SceneParams: span_count (1~5) + pier_type (SingleColumn/MultiColumn) 추가.
- span_m 의미 변경: 전체 교량 길이 → 경간당 길이. total = span_m × span_count.
- pier_ir_for_params() helper: 기본 사각 기둥·2m CSB·2.5m TB·5m column_height.
- build_bridge_scene / build_selectable_scene:
  · 거더: 경간마다 독립 세트 (span_count × girder_count 개)
  · 데크 슬래브: 전 구간 연속 1개
  · 받침: 모든 지점 (교대 2 + 교각 span_count-1)
  · 교각: 내부 지점 span_count-1 개 (새 기능)
  · 교대: 양 끝 (z=-800, z=total_mm)
  · 가로보: 경간마다 반복
  · 신축이음: 모든 지점 (선택적)
- build_background_scene + scene_extents: total_mm 기준으로 ground·alignment 길이 확장.
- project_file: version=2, span_count·pier_type 필드 추가 (v1 호환 default 값).
- UI ribbon: "경간 수" 슬라이더 + "교각 형식" T/π 선택.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 12:37:14 +09:00
minsung
e4ed82f8bc fix: occt.rs unused_mut 경고 제거
breast wall 메시 변수를 추가 수정 없이 바로 parts 에 push 하므로 mut 불필요.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 12:14:18 +09:00
minsung
750ac2247a fix: 카메라 회전 방향 반전
사용자 요청: 마우스 드래그 회전 방향이 직관과 반대라 반전.
- yaw:   delta_x * 0.005 부호 반전 (+= → -=)
- pitch: delta_y * 0.005 부호 반전 (-= → +=)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 12:04:12 +09:00
minsung
4b8a5db4a7 feat: 뷰어 타이틀에 빌드 timestamp 표시 — stale 바이너리 판별
사용자 스크린샷에서 타이틀이 'Sprint 4 — Full Bridge / OcctKernel' (구버전
문자열) 으로 표시됨 → 바이너리가 최근 수정(Ortho 카메라·받침 fix 등) 이후
재빌드되지 않은 채 실행 중임을 확인.

앞으로는 타이틀에 'cimery viewer [OcctKernel] — build 2026-04-15 HH:MM:SS'
형식으로 빌드 시각이 박혀서 실행 중 바이너리가 최신인지 즉시 판별 가능.

변경:
- crates/viewer/build.rs 추가:
  · Windows: PowerShell Get-Date, Unix: date 명령어 사용.
  · 실패 시 epoch 초로 폴백.
  · rerun-if-changed=src 로 소스 변경 시 자동 갱신.
- lib.rs: BUILD_TS = env!("BUILD_TIMESTAMP") 상수 도입, 타이틀 포맷 변경.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 11:07:33 +09:00
minsung
2cb549fd9f feat: Orthographic 카메라 추가 — 실측 확인용
사용자 피드백: 거더 높이 변경 시 차이가 미미해 보이는 것은 원근 투영의
시각 효과일 수 있음. 평행(Orthographic) 투영으로 보면 거리 무관 실측
크기가 그대로 보여 모델이 실제로 변하는지 객관적으로 확인 가능.

변경:
- camera.rs: Projection enum (Perspective / Orthographic) 추가.
  - Camera.projection 필드 + view_proj() 분기.
  - Ortho 반높이 = radius * tan(fov_y/2) → 전환 시 시각 스케일 일치.
  - toggle_projection() 메서드.
- lib.rs:
  - 카메라 초기값 projection: Perspective.
  - 키 O → 투영 토글.
  - egui 표시 섹션에 투영 버튼 추가 (◇ Perspective / ■ Ortho).

사용: 거더 높이 슬라이더 조정 → Apply → O 키로 Ortho 전환 → 모델 치수
실측 확인.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 10:20:59 +09:00
minsung
e986604f49 fix: 카메라 타겟이 항상 지반 아래를 가리키던 버그
[원인]
scene_extents 가 반환하는 BB 는 지반·교대 푸팅까지 포함 →
  top_y = girder_h + slab + 200
  bot_y = -(girder_h + 4000)
center Y = (top_y + bot_y)/2 = (slab - 3800)/2 ≈ -1790mm (지반 아래 1.8m)

더 큰 문제: top/bot 이 girder_h 에 따라 같은 비율로 변해서 center Y 는 고정.
→ girder_h 가 바뀌어도 카메라 타겟은 거더 중심을 추적하지 않음.
→ 거더가 실제론 커졌어도 카메라가 항상 지반 아래를 보기 때문에, 슬래브만
   화면 위쪽으로 멀어지고 거더는 그대로 있는 것처럼 인식됨.

[수정]
- rebuild_mesh(): zoom_extents 에 전달할 Y 범위를 [0, girder_h+slab] 로 제한
  → target Y = (girder_h + slab)/2, 거더·데크 중심으로 카메라가 추적.
- 초기 카메라: cy 를 scene_extents 중심 대신 (girder_h+slab)/2 로 설정.

결과: 거더 높이를 올리면 카메라 target 도 비례해 위로 이동 → 거더가 화면
중앙에서 자라는 것이 보이고, 슬래브는 그 위쪽에 붙어 함께 올라감.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 10:01:35 +09:00
minsung
24b15f15ec fix: 거더 높이 변경 시 씬 미갱신 + 받침 치수 오류 수정
[버그 1] Apply 후 카메라 자동 피트 누락
- rebuild_mesh() 에서 scene_extents 만 업데이트하고 camera target/radius 는
  갱신하지 않아, 거더 높이를 올려도 카메라가 구 씬 중심을 가리켜 변화가 안 보임.
- 수정: rebuild_mesh() 끝에 camera.zoom_extents(mn, mx) + update_camera() 추가.

[버그 2] bearing.rs plan_length / plan_width 방향 오류
- plan_length(350mm, 경간 방향)를 profile X(횡방향)에, plan_width(450mm, 횡방향)를
  sweep Z(경간방향)에 사용 → 받침이 90° 회전된 치수로 생성됨.
- Z 센터링 오프셋도 plan_width/2=225mm 로 계산 → 올바른 plan_length/2=175mm 보다
  50mm 더 교대 밖으로 튀어나옴 (스크린샷의 부유 블록).
- 수정:
  · bearing.rs: trans_dim=plan_width(profile X), span_dim=plan_length(sweep Z)
  · bridge_scene.rs: build_bridge_scene + build_selectable_scene 의 Z 오프셋을
    z - 225 → z - plan_length/2 = z - 175 로 변경.

cargo check --workspace 0 errors/warnings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 09:30:13 +09:00
minsung
824c18610b Sprint 23/24 — Tauri v2 앱 래핑 + salsa 0.16 증분 쿼리 백엔드
All checks were successful
Publish ParaWiki / build-and-deploy (push) Successful in 34s
Sprint 23: cimery-app을 Tauri v2 앱으로 전환.
- tauri.conf.json, capabilities/default.json, frontend/index.html 추가
- src/commands.rs: 7개 IPC 커맨드 (launch_viewer, 프로젝트 관리, USD/CSV 익스포트)
- 뷰어 사이드카: std::process::Command 방식 (PATH + exe-dir 탐색)
- release.yml: 3단계 멀티플랫폼 릴리스 워크플로로 교체

Sprint 24: cimery-incremental에 salsa 0.16 백엔드 추가.
- salsa_db.rs: BridgeQueryGroup + SalsaIncrementalDb<K>
- --features salsa-backend 로 활성화 (기본값: 수동 tracking, WASM 안전)
- IR 전 구조체 + Mesh + KernelError에 PartialEq/Eq 추가
- 테스트 20개 전부 통과 (수동 12 + salsa 8)
- cargo check --workspace 0 errors/warnings

기타: viewer/dsl 컴파일 경고 제거, wiki 실행 가이드 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 09:09:47 +09:00
minsung
1f9ca3a00f Sprint 14~22 — egui 리본 UI + OcctKernel B-rep + 가로보/신축이음 + 선형 좌표 + USD 익스포트 + WASM + CI/CD + 테스트 4층
Sprint 14: egui TopBottomPanel 리본 + CollapsingHeader SidePanel (상부구조·추가부재·선형·프로젝트)
Sprint 15: IncrementalDb 전 Feature 타입 확장 (girder→7종), dirty-tracking 20 unit tests
Sprint 16: Gitea + GitHub Actions CI/CD (check/test/clippy/fmt + 멀티플랫폼 릴리스)
Sprint 17: AlignmentTransform + AlignmentScene — 선형 국소 프레임 → 세계 좌표 변환
Sprint 18: OcctKernel 교각(16각형 기둥+코핑) + 교대(흉벽+푸팅+날개벽) B-rep
Sprint 19: CrossBeamIR + ExpansionJointIR — IR/DSL/kernel/scene 전 계층, sweep_profile_flat_x
Sprint 20: 테스트 4층 — Layer1 insta 스냅샷(7종), Layer2 기하 불변량(19), Layer3 두-커널(7), Layer4 proptest(7) — 61 tests pass
Sprint 21: cimery-usd PureRustKernel 실제 기하 변환 + BridgeExporter 증분 캐시
Sprint 22: viewer wasm feature + wasm-bindgen/web-sys + GitHub Actions Cloudflare Pages 배포

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 08:18:06 +09:00
minsung
81349c97d2 Sprint 11/12/13 — 선택하이라이트 + 저장/로드 + Tauri앱 스켈레톤
Sprint 11 (Selection highlight + 단면 UI):
- FeatureDraw: CPU 정점 저장, update_highlight() — 선택 시 yellow-orange
- 렌더 루프: background mesh(지면+선형) + 피처별 독립 draw call 분리
- SceneParams: GirderSectionType (PscI / SteelBox), show_alignment
- egui: 단면형식 ComboBox, 선형표시 checkbox
- SteelBox 단면 지원 (span 비례 자동 치수)
- build_background_scene(): 지면+선형만 반환

Sprint 12 (Project save/load):
- project_file.rs: ProjectFile struct, to_params/from_params, save/load JSON
- egui: 💾 저장 / 📂 불러오기 버튼
- projects/ 폴더 자동 생성

Sprint 13 (Tauri app skeleton):
- crates/app/: Cargo.toml + main.rs (Tauri v2 통합 scaffold)
- 기동 시 PureRustKernel 동작 검증
- Tauri setup checklist 주석으로 문서화
- workspace에 cimery-app 추가

cargo check --workspace 통과

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 22:59:11 +09:00
minsung
5d89db5117 Sprint 9/10 — 지면+선형 시각화 + 피처 선택
Sprint 9 (bridge_scene):
- 지면(Ground plane): 교량 하부 어두운 올리브 색 평면
- 선형(Alignment): 주황색 얇은 봉 (Z축 방향 경간 전체)
- 색상 추가: COL_GROUND, COL_ALIGNMENT

Sprint 10 (selection):
- FeatureDraw: 피처별 GPU 버퍼 + AABB + 선택 상태
- build_selectable_scene(): 거더/슬래브/받침/교대 개별 메시
- ray_aabb(): 레이-AABB 교차 판정 (좌클릭 피킹)
- egui 패널: 선택된 피처 이름 오렌지색 표시
- 선택 하이라이트는 Sprint 11에서 색상 override로 구현

cargo check 통과

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 22:49:57 +09:00
minsung
419c459074 bridge_scene: girder_height 파라미터 단면 기하학에 실제 반영
kds_standard() 대신 SceneParams.girder_height를 PscISectionParams.total_height에 연결.
슬래브 위치와 거더 단면 높이가 이제 함께 변경됨.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 22:33:14 +09:00
minsung
263806b834 Sprint 6/7/8 — Alignment 로더 + CSV 라운드트립 + IncrementalDb 스캐폴드
Sprint 6 (Alignment JSON 로더):
- AlignmentIR: from_file(), position_at(station), total_length_m()
- AlignmentStation, AlignmentSpecs in ir crate
- alignments/BR-001-test.json: 40m 직선 테스트 선형

Sprint 7 (CSV 라운드트립):
- csv_template.rs: girder_params() 레지스트리
- girder_to_csv_template(): 헤더+기본값 CSV 출력
- girder_from_csv(): CSV → Vec<GirderIR> 파싱
- 테스트 3개 (template, multi-row, invalid span)

Sprint 8 (IncrementalDb 스캐폴드):
- incremental_scene.rs: IncrementalBridge<K>
- 안정적 girder ID (슬롯 기반), DB 캐시 → X-translate
- Sprint 9에서 전체 Feature IncrementalDb 통합 예정

cargo test 60개 전부 통과

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 20:55:16 +09:00
minsung
257630f64b viewer: 슬라이더 자동적용 제거 — Apply 버튼 명시적 클릭만
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 20:51:13 +09:00
minsung
2550e13b10 viewer Sprint 5 완성 — 한글 폰트 + 슬라이더 자동 재생성
- Windows Malgun Gothic 폰트 로드 (한글 지원)
- param_slider! 매크로: drag_released() / lost_focus() 시 자동 rebuild_mesh()
- "▶ 적용 (Apply)" 버튼은 manual fallback으로 유지

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 20:50:37 +09:00
minsung
a05e8f5dea viewer: egui depth format 불일치 수정 + 변수명 경고 제거
- egui_wgpu::Renderer:🆕 depth format None (UI는 depth 불필요)
- bridge_scene.rs: SPAN_M 등 snake_case로 전환

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 20:44:26 +09:00
minsung
23ddcfade0 Sprint 5 — 인터랙티브 파라메트릭 + egui 속성 패널
- SceneParams: 경간/거더수/간격/높이/슬래브두께 — 실시간 변경 가능
- egui SidePanel(좌측): 슬라이더 편집 → ▶ 적용 → 씬 재생성
- rebuild_mesh(): 파라미터 변경 시 GPU 버텍스·인덱스 버퍼 재생성
- wgpu 22 + egui-wgpu 0.29: forget_lifetime() 로 render pass 전달
- 3D 인코더와 egui 인코더 분리 (wgpu 22 lifetime 호환)
- build_bridge_scene(&SceneParams): 경간·거더수·간격 파라메트릭

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 20:35:43 +09:00
minsung
3645b85828 받침 중심 정렬 + 부재별 색상 구분
bearing.rs: X 중심, Y 하방향 (-h to 0) 기하학 수정
bridge_scene.rs: 받침 X 오프셋 제거 (girder 정렬)
Mesh: colors 필드 추가 + recolor() 메서드
sweep.rs / occt.rs: 기본 콘크리트 색 자동 채움
bridge_scene: 부재별 색상 (거더/슬래브/받침/교대)
shader.wgsl: base_color 입력 → 조명 계산에 적용

선택(Selection) 기능은 계획대로 별도 Sprint에 구현.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 20:26:40 +09:00
minsung
eac079f46c bridge_scene: 교대 X 이중 오프셋 수정 — 중심 정렬
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 20:18:57 +09:00
minsung
13b1c8dfe8 abutment: X/Z 방향 수정 — 흉벽이 경간에 수직으로 배치
kernel/abutment.rs:
- 흉벽(breast wall): X=횡단(bw_w), Y=높이(bw_h), Z=두께(bw_t) — 올바른 방향
- 기초(footing): X=횡단(ft_w), Y=두께(ft_t), Z=경간방향(ft_l)
- 날개벽(wing wall): ±X 방향으로 연장

viewer/lib.rs: unused imports 제거 (경고 해소)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 20:15:51 +09:00
minsung
096fc133c4 viewer: Pan + ZoomExtents + 표준 뷰 단축키
camera.rs:
- pan(dx, dy): Shift+중간버튼으로 target 이동 (화면 평면 이동)
- zoom_extents(mn, mx): E키로 전체 씬 맞춤
- set_standard_view(StandardView): 축 고정 뷰
- StandardView: Top(7) / Front(1) / Right(3) / Left(4) / Iso(Home)

lib.rs:
- shift_pressed 추적 (ModifiersChanged)
- Shift+중간버튼 드래그 → pan
- E → ZoomExtents
- 1/3/4/7/Home → 표준 뷰 스냅
- scene_mn/mx 저장 → zoom_extents에 전달

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 20:11:07 +09:00
minsung
3359475879 Sprint 4 — Full bridge scene (Girder×5 + DeckSlab + Bearing×10 + Abutment×2)
viewer/bridge_scene.rs: BridgeScene compositor
- 5× PSC-I Girder (2500mm c/c)
- DeckSlab (12000mm, 220mm thick, top of girders)
- 10× Elastomeric Bearing (5 per abutment end)
- 2× ReverseT Abutment (start & end)
- sweep::merge_meshes로 단일 메시 합성
- scene_extents()로 카메라 자동 배치

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 20:08:21 +09:00
minsung
c20d5b21e1 viewer: --features occt 시 OcctKernel B-rep 렌더링 연결
- viewer/Cargo.toml: occt feature → cimery-kernel/occt 전파
- lib.rs: cfg(feature = "occt") 분기
  - OcctKernel: OCCT B-rep PSC-I + BRepMesh 테셀레이션
  - PureRustKernel: 기본값 (occt 없을 때)
- 타이틀 자동: "OcctKernel B-rep" vs "PSC-I PureRustKernel"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 19:42:23 +09:00
minsung
0bc3f12688 OcctKernel 구현 — PSC-I B-rep sweep + BRepMesh 테셀레이션
- cimery-kernel/src/occt.rs: OcctKernel (--features occt 전용)
  - Workplane::xy().sketch()로 PSC-I 14-vertex 2D 프로파일 생성
  - Face::extrude(DVec3) → Solid (OCCT B-rep)
  - Mesher::try_new() + mesh() → 테셀레이션
  - cimery Mesh로 변환 (vertices/normals/indices)
  - 기타 Feature: PureRustKernel 위임
- kernel/Cargo.toml: glam 0.24 (opencascade-rs 동일 버전)
- cargo build --features occt 빌드 확인 완료

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 19:37:51 +09:00
minsung
bdacea5253 Sprint 3 — Must Feature 5종 추가 (상부→하부 순서)
상부 구조물:
- DeckSlabIR + DeckSlabBuilder + 기하학 (직사각형 슬래브 스위프)

연결부:
- BearingIR + BearingBuilder (카탈로그 기반, KDS 기본값 포함)

하부 구조물:
- PierIR + PierBuilder + 기하학 (다주 지원, 코핑 포함)
- AbutmentIR + AbutmentBuilder + 기하학 (흉벽 + 기초 + 날개벽)

core에 BearingType·PierType·ColumnShape·AbutmentType 열거형 추가
kernel: sweep.rs 공유 모듈 (sweep_profile_flat·box·prism·merge)
psc_i.rs → sweep.rs 의존으로 리팩터
GeomKernel trait에 4개 메서드 추가 (상부→하부 문서화 주석)

cargo test 57개 전부 통과

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 19:27:57 +09:00
minsung
40857f39c5 viewer: PureRustKernel로 교체 — PSC-I 단면 렌더 확인
StubKernel(박스) → PureRustKernel(실제 PSC-I 14-vertex 스위프).
플랜지·웹·헌치 형상 정상 렌더 확인 (스크린샷).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 19:06:24 +09:00
minsung
9cbe76cc5e cimery Sprint 2 — PSC-I 기하학 + viewer 개편 + OCCT optional
kernel:
- PureRustKernel: PSC-I 단면 14-vertex polygon 스위프, flat normals
  56 triangles / 168 vertices, 법선 단위벡터 검증 포함
- opencascade 의존성 optional feature (--features occt)로 격리
  → OCCT 없이도 전체 빌드 가능
- psc_i.rs: 프로파일 검증, AABB, 법선 테스트 6개

viewer:
- camera.rs: arcball orbit (middle-mouse drag + scroll zoom)
- shader.wgsl: MVP matrix uniform + 방향성 조명 (콘크리트 베이지)
- lib.rs: depth buffer, index 렌더, 실제 Mesh 업로드
  StubKernel → PureRustKernel → OcctKernel 교체 경로 문서화

CLAUDE.md: MVP 품질 원칙 강화 ("아키텍처 임의 변경 절대 불가")

cargo test --workspace (viewer 제외) 43개 전부 통과

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 18:48:10 +09:00
minsung
62ddf3aea6 cimery Sprint 1 — Rust 워크스페이스 + 전 계층 파이프라인
8개 크레이트 구현, cargo test 32개 전부 통과:
- core: Mm/M 단위 newtype, UnitExt 리터럴, FeatureError
- ir: GirderIR + 전 단면 파라미터(PSC-I/U/SteelBox/PlateI) serde JSON
- dsl: Girder builder + 검증 (경간 범위·count·spacing)
- kernel: GeomKernel trait + StubKernel (box mesh, AABB)
- incremental: dirty-tracking IncrementalDb (salsa 업그레이드 경로 주석)
- evaluator: 상태 없는 IR→kernel 브리지
- usd: USDA 1.0 텍스트 익스포트 (CimeryBridgeAPI·GirderAPI schema)
- viewer: wgpu 22 + winit 0.30 컬러 삼각형 (Sprint 1 proof-of-concept)

Sprint 2 다음 단계:
- opencascade-rs로 StubKernel 교체 (실제 PSC-I sweep)
- viewer에서 Girder Mesh 렌더 + 카메라 orbit

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 17:46:14 +09:00