# FikoCAD Yerel Dosya Formatı (`.fikocad`) — Spesifikasyon v1

Native fikatia-local platformunun KENDİ belge formatı. Modelin tam durumu
(ürün ağacı + gövdeler + kamera) tek, ikili, sıkıştırılmış dosyada saklanır.
Kaydet → kapat → aç sonrası model **aynı kamera noktasında** geri gelir.

## 1. Tasarım araştırması ve seçilen yaklaşım

| Konu | Seçenekler | Seçim + gerekçe |
|------|-----------|-----------------|
| Konteyner | glTF-GLB chunk, RIFF, özel chunk | **Özel chunk'lı ikili** — GLB'nin (magic+sürüm+ardışık `[uzunluk\|tip\|veri]` chunk) fikrini alır; bağımlılık yok, ileri-uyumlu (bilinmeyen chunk atlanır). |
| Sıkıştırma | zstd, lz4, deflate/zlib | **deflate (miniz `mz_compress2`)** — miniz zaten vendored (`ucuncu_taraf/miniz`), self-contained. zstd daha iyi oran/hız verir (öneri: sonraki dalga), ama prototip için miniz yeterli. Büyük ikili bloklar (B-rep) sıkıştırılır; küçük metadata ham. |
| Geometri | mesh dökümü, kendi B-rep, OCCT `BinTools` | **OCCT `BinTools_ShapeSet` ikili B-rep** (`geometri::govdeBaytYaz`/`govdeBaytOku` — projede zaten var). Parametrik B-rep tam korunur, mesh'ten çok daha küçük, yüklemede yeniden tesselate edilir (mesh cache'e gerek yok). |
| Serileştirme | FlatBuffers/Cap'n Proto (zero-copy), el ile POD | **El ile POD, little-endian** — şema küçük ve sabit; harici derleyici/bağımlılık istemez, tek geniş `read` + yerinde parse ile zero-copy'ye yakın. |
| Okuma | mmap, akış, tek read | **Tek geniş read → bellek-içi parse** — dosya tümüyle okunur, chunk'lar imlecle gezilir; kopya minimal, alloc'lar toplu. |

## 2. Bayt düzeni

- **Endian:** little-endian (hedef x86-64). Başlıkta işaretlenir.
- **Tipler:** `u8/u16/u32/u64` işaretsiz tam sayı, `f32/f64` IEEE-754, `str` = `u32 uzunluk` + UTF-8 baytları.

### 2.1 Dosya başlığı (12 bayt)

| Ofset | Tip | Alan | Değer |
|------|-----|------|-------|
| 0 | u8[4] | magic | `'F','K','C','D'` (0x46 4B 43 44) |
| 4 | u16 | surumBuyuk | 1 |
| 6 | u16 | surumKucuk | 0 |
| 8 | u32 | bayrak | bit0 = little-endian (=1); diğerleri 0 |

Başlıktan sonra **chunk dizisi** EOF'a kadar sürer.

### 2.2 Chunk başlığı (24 bayt) + gövde

| Tip | Alan | Açıklama |
|-----|------|----------|
| u32 | etiket | 4-karakter tag ('META','CMRA','TREE','NODE'...) |
| u8  | sikistirma | 0 = ham, 1 = deflate (zlib) |
| u8[3] | ayrik | 0 (hizalama/gelecek) |
| u64 | hamBoyut | açılmış gövde boyutu |
| u64 | diskBoyut | diskte yatan gövde boyutu (ham ise = hamBoyut) |
| u8[diskBoyut] | govde | (sıkıştırılmışsa deflate akışı) |

**İleri-uyumluluk:** okuyucu tanımadığı `etiket`'i görürse `diskBoyut` bayt atlar.
**Sürüm:** `surumBuyuk > 1` → okuma reddedilir (Türkçe hata), çökme yok.

## 3. Chunk'lar (v1)

### META (ham)
`u32 grupSayi`, `u32 dugumSayi`, `f32 birim` (1.0 = mm).

### CMRA (ham) — kamera durumu
`f32 yonelim[4]` (quat x,y,z,w), `f32 odak[3]`, `f32 mesafe`, `f32 fovDeg`,
`u8 ortografik`, `f32 orbitHassas`, `f32 panHassas`, `f32 zoomOran`, `f32 yumusatma`.
Türetilmiş/geçici alanlar (yakın/uzak düzlem, derinlik ipucu) **yazılmaz**.

### TREE (deflate) — ürün ağacı grupları
`u32 sayi`, ardından her grup: `u32 kimlik`, `u32 ust` (0=kök), `u8 gorunur`, `str ad`.
Not: otomatik **"Origin"** grubu ve referans geometri (düzlem/eksen) yazılmaz
(yeni belgede zaten kurulur).

### NODE (deflate) — gövde düğümleri
`u32 sayi`, ardından her düğüm:
`u32 kimlik`, `u32 ust`, `u8 tip` (DugumTip), `u8 gorunur`,
`f32 renk[3]`, `f32 saydamlik`, `f32 gorselOran`,
`f32 p1,p2,p3,aciZDerece`,
`f64 konum[3]`, `f64 yonelim[4]`, `f64 olcek[3]` (TRS dönüşümü),
`str ad`, `str brep` (BinTools ikili B-rep; boş olabilir),
`u32 yuzRenkSayi` + `f32[3] × yuzRenkSayi` (STEP per-yüz renkleri).

**Not — per-yüz renk:** OCCT `BinTools` yalnız topoloji/geometri saklar, XCAF renk
özniteliklerini **taşımaz**. STEP'ten gelen yüz-başı renkler (`BrepGovde.yuzRenkleri`)
bu yüzden NODE kaydında ayrı dizide tutulur, yüklemede `ucgenle`'den önce geri atanır
→ çok-renkli STEP modelleri round-trip'te renklerini korur. (Format v1.1)

Tüm NODE gövdesi (B-rep + renk baytları dahil) tek deflate çağrısıyla sıkıştırılır.

## 4. Kimlik yeniden eşleme

Kimlikler orijinal `Varlik` (ECS entity) değeridir. Yüklemede yeni belgede yeni
kimlikler üretileceğinden, önce tüm gruplar oluşturulup `eski→yeni` haritası kurulur,
sonra üst bağları ve düğüm ebeveynleri bu harita üzerinden çözülür. Haritada olmayan
ebeveyn (atlanan grup/referans) → kök (VARLIK_YOK), güvenli düşüş.

## 5. İlk prototipte kapsanan / ertelenen

**Kapsanan:** katı gövdeler (Kutu/Silindir/Küre/Koni/Boolean/İthal), tam B-rep
(BinTools), TRS dönüşüm, per-gövde renk + **STEP per-yüz renkleri**, saydamlık/
görünürlük, ürün ağacı (grup hiyerarşisi), kamera (aynı bakış noktası). Sıkıştırma +
chunk konteyner + sürüm/çökme koruması.

**Ertelenen (sonraki dalgalar):**
- Parametrik feature geçmişi (RecomputeMotor DAG, Part/GSD feature ağacı) — şu an
  yalnız son B-rep saklanır; yüklenen düğüm İthal katı gibi geri gelir (parametreler
  p1..p3 de yazılır ama feature zinciri replay edilmez).
- Sketch düğümleri (EskizVeri + kısıtlar), GSD Tel/Yüzey, CAM takım yolları.
- Mesh-only import (.wrl/.FikoOp, brep'siz düğümler).
- zstd sıkıştırma; blok/mmap okuma.
- Yükleme semantiği: prototipte **ekleyerek** yükler (mevcut sahneyi silmez) +
  kamerayı uygular → boş/yeni belgeye açınca model birebir geri gelir.

## 6. Uygulama konumları

- Format çekirdeği (saf, test edilebilir): `motor/io/src/fiko_format.cpp`,
  başlık `motor/io/include/fiko/io/fiko_format.hpp` (`fikoYaz`/`fikoOku` — akış yok,
  `std::string` tampon üzerinde; `fikoKaydet`/`fikoYukle` — Sahne+OrbitKamera düzeyi).
- Kamera anlık geri yükleme: `OrbitKamera::durumAta(...)` (motor/render).
- Uygulama teli: `uygulama/fikocad/dosya_islemleri.cpp` (`fikoAc`/`fikoKaydetKomut`/
  `fikoYol`, `yolAc` `.fikocad` dalı, `dosyaSec` `.fikocad` filtresi) + `main.cpp`
  (Dosya menüsü komutları + Ctrl+S / Ctrl+O kısayolları). Sürükle-bırak `yolAc`'tan
  geçtiği için `.fikocad` otomatik tanınır.
- Round-trip testi: `motor/io/test/test_fiko_format.cpp`.
