# CAM İnteraktif 3D Şema + Sahneden Seçim + Makro 3D Önizleme — Native Spec

> **Amaç:** Web `fiko-cam/` sisteminin (fikoyt-sistem) op penceresi-içi **interaktif 3D şema**, **her geometri girdisini ana sahneden tıkla-seç** ve **makro 3D önizleme** davranışlarını fikatia-local'e (C++23/Vulkan/ImGui/OCCT) **birebir** taşımak.
> **Kural:** Web kodu kopyalanmaz; yalnız davranış/algoritma. Placeholder buton YASAK — her akış uçtan uca.
> **Zemin:** Native `SecimOge{govde, alt}` zaten yüz/kenar/nokta ordinali taşıyor; `BrepGovde::yuzKonturlari/yuzBilgi/kenarBilgi/noktaKonum` zaten var → web'in mesh-boundary yeniden-inşasına GEREK YOK, OCCT'den exact okunur. Bu native'i web'den DAHA temiz yapar.

---

## 0. Web davranışının özeti (kaynak dosyalar → satır)

| Web öğe | Dosya | Rol |
|---|---|---|
| İnteraktif şema (blok/cep/limit/offset/toolaxis) | `fiko-strateji-3d.component.ts` (283 sat) | Op tipine göre şematik 3D, rol tıkla→seçim, offset çift-tık |
| Makro 3D önizleme | `fiko-makro-3d.component.ts` (194 sat) | Giriş/çıkış yolu polyline + düğüm + ok + ölçü etiketi |
| Buton→seçim/rol dispatch | `fiko-cam-dialog.ts` (787 sat) | `stratejiRol()` 705-715, `geoDuzlemSec()` 461-470, `noktaSec/konturSec/kenarSec/stokKontur/adaSec` 771-778 |
| Seçim motoru | `fiko-cam.yonetici.ts` 638-951 | `secBaslat/secTik/hoverTik/enYakinKenarGrup/yuzKonturAl/secimGorselle/secimDurumBildir` |

**Web'in kritik gerçeği:** Web'de mesh'te `attributes['grup']` var; `fid = grup.getZ(hit.faceIndex*3)` ile yüz kimliği çözülür, sonra `yuzKonturAl` önce `brepKontur(fid)` (segment line/arc, arc ~7.5° örneklenir) yoksa mesh boundary loop (`yuzKonturXY`, shoelace en-büyük-alan) çıkarır. **Native'de bu iş `BrepGovde::yuzKonturlari(ordinal)` ile TEK ÇAĞRIDA yapılır** (ilk kontur dış sınır, sonrakiler ada/delik).

---

## 1. SEÇİM AKIŞI — NATIVE PLANI (uçtan uca)

### 1.1 Mevcut native altyapı (spec buna bağlanır)

| Native varlık | Yer | Ne verir |
|---|---|---|
| `SecimOge{u32 govde, u32 alt}` | `sahne.hpp:31` | alt = yüz/kenar/nokta ordinali (1-tabanlı, TopExp sırası) |
| `SecimKip{Govde,Yuz,Kenar,Nokta}` | `sahne.hpp:28` | seçim seviyesi |
| `SecimSistemi` | `secim_sistemi.hpp` | GPU pick, `vurguTur()` (0 gövde,1 yüz,2 kenar,3 nokta), `hoverCozumle`, `tikla` |
| `sahne.vurgu` (`SecimOge`) | `sahne.hpp:209` | imleç altındaki öğe (GPU pick ile beslenir, her kare) |
| `imlecVurus(px,py,IsinVurus&)` | `main.cpp:739` | ışın→yüzey; `vr.govde/nokta/normal/t` (CPU raycast) |
| `BrepGovde::yuzKonturlari(ord, sapma)` | `brep.hpp:80` | yüzün kapalı konturları (yerel; [0]=dış sınır, [1..]=ada) |
| `BrepGovde::yuzBilgi(ord, YuzBilgi&)` | `brep.hpp:71` | duzlemMi/normal/merkez/silindirMi/eksen/yaricap |
| `BrepGovde::kenarBilgi(ord, KenarBilgi&)` | `brep.hpp:70` | dogruMu/cemberMi/bas/son/merkez/yaricap |
| `BrepGovde::noktaKonum(ord, Vec3d&)` | `brep.hpp:69` | köşe noktası konumu |
| `BrepGovde::kenarNoktalari(ord)` | `brep.hpp:75` | kenar örnek noktaları (kenar-zincir kontur için) |
| `OlcumSistemi` seçim kalıbı | `olcum_sistemi.hpp` + `main.cpp:2247-2255` | **birebir örnek:** dialog açıkken tık → `secimAl(vurgu.govde, vurgu.alt, vurguTur)` |

**Karar:** Web `FikoCamYonetici`'nin seçim bölümü native'de **`CamSecimSistemi`** (yeni; `OlcumSistemi` kalıbında) olur. `CamSistemi`'ne bir üye olarak eklenir; makro/plugin/olay erişimi merkezi registry'den doğuştan gelir (MEMORY: fikatia-mimari-ilke).

### 1.2 Uçtan uca akış (op penceresinde "Profil/Kontur" örneği)

```
[Op penceresi Geometri sekmesi]
   ImGui::Button("⬚ Profil/Kontur")  →  camSecim.baslat(CamSecimKip::Kontur, op, gc)
                                          │
                                    (secModu=Kontur, secOp=op; SecimKip::Yuz'e geç
                                     → GPU pick yüz filtrele; HUD "Kontur seç · N seçili")
                                          ▼
[Ana viewport sol-tık]  main.cpp fare.sol bloğu (2247 kalıbı):
   if (camSecim.aktif() && camSecim.op == /*bu op*/) {
       camSecim.tik(sahne.vurgu, secimSis.vurguTur(), imlecVurus_lambda);
   } else if (olcum.acik ...) { ... } else secimSis.tikla(ctrl);
                                          ▼
[CamSecimSistemi::tik]  moda göre:
   Kontur/Ada:  ord = vurgu.alt (yüz); Dugum* d=sahne.bul(vurgu.govde);
                d->brep->yuzKonturlari(ord) → konturlar (yerel).
                DÜNYA'ya taşı: d->matris() uygula (web LOCAL bırakıyor ama native
                op geometrisi web'de local; native'de tutarlılık için: op.geometri
                XY'yi part-op eksen sistemine indir — bkz 1.5).
                → op.geometri.konturlar = [dış]; ada varsa op.geometri.adalar += kalan
                → op.geometri.ustZ = yüz merkez Z; op.geometri.ustZRef = ord (associatif)
   Nokta:       imlecVurus → vr.nokta (dünya) → op.geometri.noktalar += {x,y,z}
   Duzlem:      YuzBilgi/merkez Z (yerel) → duzlemAyarla(z, ord)  [callback]
   NoktaRef:    imlecVurus → yerel (x,y) → noktaRefAyarla(x,y)   [Limit1/2]
   Toolaxis:    YuzBilgi.normal (dünya'ya normalMatris ile) → op.takimYonu{yon,Yuzey,ord,origin}
   Kenar:       ekran-uzaklığı (bkz 1.4) → toggle → zincirle → op.geometri.konturlar
                                          ▼
   op.bayat = true;  camSecim.gorselle(op);  gc();  (pencere alanları + şema yenilenir)
   HUD sayaç güncelle (secimDurumBildir).  [Kontur/Toolaxis/Duzlem/NoktaRef → tek tık sonrası
   camSecim.bitir(); Nokta/Ada/Kenar → mod açık kalır, ESC/tekrar-buton ile biter.]
```

### 1.3 `CamSecimSistemi` API (öneri — `motor/cam/include/fiko/cam/cam_secim.hpp` YENİ, `OlcumSistemi` kalıbı)

```cpp
enum class CamSecimKip { Yok, Kontur, Ada, Nokta, Kenar, Duzlem, NoktaRef, Toolaxis, Stok };

class CamSecimSistemi {
public:
  CamSecimSistemi(Sahne& sahne, CamSistemi& cam, OlayGunlugu& olaylar);

  // ---- Mod başlatma (web camXxxSecBaslat karşılıkları) ----
  // gc = pencere/şema yenileme geri çağrımı. Toggle: aynı mod+op → bitir.
  void konturBaslat(CamOperasyon& op, std::function<void()> gc);
  void adaBaslat(CamOperasyon& op, std::function<void()> gc);
  void noktaBaslat(CamOperasyon& op, std::function<void()> gc);
  void kenarBaslat(CamOperasyon& op, std::function<void()> gc);
  // duzlemAyarla: seçilen yüzün yerel Z'si + faceId (associatif ustZ/altZ/güvenlik/…)
  void duzlemBaslat(CamOperasyon& op, std::function<void(f64 z, u32 faceId)> ayarla,
                    std::function<void()> gc, const char* etiket);
  // noktaRefAyarla: Limit1/2 — yerel (x,y) sınır noktası
  void noktaRefBaslat(CamOperasyon& op, std::function<void(f64 x, f64 y)> ayarla,
                      std::function<void()> gc, const char* etiket);
  void toolaxisBaslat(CamOperasyon& op, std::function<void()> gc);
  void stokKonturAta(CamOperasyon& op);   // seçim gerektirmez: part-op stok kutusu → kontur

  // ---- Ana viewport tık/hover kancaları (main.cpp'den çağrılır) ----
  bool aktif() const { return kip_ != CamSecimKip::Yok; }
  const CamOperasyon* op() const { return op_; }
  // vurgu = sahne.vurgu (GPU pick), vurguTur = secimSis.vurguTur().
  // isinVur = imlecVurus lambda köprüsü (serbest nokta/dünya nokta için).
  void tik(SecimOge vurgu, u32 vurguTur,
           const std::function<bool(Vec3f&, Vec3f&)>& isinVur);   // → (dünyaNokta, normal)
  void hover(SecimOge vurgu, u32 vurguTur, i32 imlecX, i32 imlecY);  // önizleme vurgusu
  void bitir();                          // mod kapat + gc + HUD temizle
  SecimKip beklenenKip() const;          // GPU pick filtresi (Kontur/Ada/Duzlem/Toolaxis→Yuz, Nokta→Yuz+serbest, Kenar→Kenar)

  // ---- HUD (op penceresi + ana ekran alt bilgi) ----
  struct Durum { CamSecimKip kip; std::string opAd, ek; int sayi; };
  bool durumVar() const; Durum durum() const;

  // ---- 3D görselleştirme (seçili kontur/nokta vurgusu — salt-kenar düğüm) ----
  void gorselle(const CamOperasyon& op);  // op.geometri.konturlar/noktalar → sahne kenar düğümü
  void hoverGorsel(...);                   // geçici mavi kontur (fog YOK)
  void gorselTemizle();

private:
  Sahne& sahne_; CamSistemi& cam_; OlayGunlugu& olaylar_;
  CamSecimKip kip_ = CamSecimKip::Yok;
  CamOperasyon* op_ = nullptr;
  std::function<void()> gc_;
  std::function<void(f64,u32)> duzlemAyarla_;
  std::function<void(f64,f64)> noktaRefAyarla_;
  std::string etiket_;
  // Kenar modu (web secEdgeIdx + kenarCache + kenarCacheNoktalar kalıbı):
  std::vector<u32> secKenarOrd_;                          // seçili kenar ordinalleri (toggle)
  std::vector<std::vector<Vec3d>> kenarCacheNok_;         // her kenar örnek noktaları (yerel)
  int sonHoverYuz_ = -1, sonHoverKenar_ = -1;
  u32 gorselDugum_ = 0, hoverDugum_ = 0;                  // sahne salt-kenar düğüm kimlikleri
};
```

**main.cpp entegrasyon (2247 kalıbının GENİŞLETİLMESİ):**
```cpp
// fare.sol bırakma bloğunda, olcum kontrolünden ÖNCE (CAM önceliği op penceresi açıkken):
if (camSecim.aktif()) {
  camSecim.tik(sahne.vurgu, secimSis.vurguTur(),
    [&](Vec3f& n, Vec3f& nm){ Sahne::IsinVurus vr;
      if (imlecVurus(lx,ly,vr) && vr.govde){ n=vr.nokta; nm=vr.normal; return true;} return false; });
} else if (olcum.acik && ...) { ... } else secimSis.tikla(io.KeyCtrl);
```
Hover (pick çözüldükten sonra, ~main.cpp 3601 civarı):
```cpp
if (camSecim.aktif()) camSecim.hover(sahne.vurgu, secimSis.vurguTur(), (i32)lx, (i32)ly);
```
GPU pick filtresi (~3593 `olcum.aktifFiltre()` yerine, CAM aktifse):
```cpp
if (camSecim.aktif()) { SecimKip k = camSecim.beklenenKip();
  secimSis.fYuz = (k==SecimKip::Yuz); secimSis.fKenar = (k==SecimKip::Kenar);
  secimSis.fNokta = (k==SecimKip::Nokta); secimSis.fGovde=false; }
```
ESC / sağ-tık iptali: `if (camSecim.aktif() && esc) camSecim.bitir();`

### 1.4 Kenar seçimi (web `enYakinKenarGrup` 22px kalıbı)

Web mesh'te EdgesGeometry'den grup üretiyor. **Native'de kenarlar zaten B-rep ordinalli** (`kenarMesh` + `kenarBilgi`). Plan:
- `kenarBaslat`: hedef gövdenin tüm kenar ordinallerini gez, her biri için `kenarNoktalari(ord)` → `kenarCacheNok_`.
- `hover/tik` kenar modunda: web `enYakinKenarGrup` — her kenarın örnek noktalarını `d->matris()` ile dünyaya taşı → `kamera.izdusum*gorunum` ile ekran pikseline projekte et → imleç-piksel uzaklığı < 22px → en yakın ordinal. (Not: native'de GPU pick zaten kenar verir — vurguTur==2 → `vurgu.alt` doğrudan kenar ordinali; **22px ekran-uzaklığı YALNIZCA fallback**, öncelik GPU pick.)
- toggle → `secKenarOrd_`; `kenarlardanKontur()` (web 919-950 uç-uca zincir, tol²=25 (5mm)²) → tek açık/kapalı XY kontur → `op.geometri.konturlar`.

### 1.5 Koordinat çerçevesi (web LOCAL vs native part-op ekseni)

Web `op.geometri` part düzleminde 2D. Native'de `PartOperasyon` bir **Machining Axis System** (`eksenOrigin/eksenX/eksenY/eksenZ`, `part_operasyon.hpp`) tutar. Yüz konturu OCCT'den **dünya-yerel gövde** uzayında gelir; op.geometri'ye yazarken:
- `ustZ/altZ` ve `konturlar (x,y)` → part-op eksen sistemine PROJEKTE et (dünya nokta → `eksenOrigin` çıkar, `eksenX/Y/Z`'e nokta çarpımı). Eksen tanımlı değilse dünya X/Y/Z varsayılır (web davranışı = identity).
- `ustZRef=faceId` associatif: `CamGeometri.ustZRef` (u32) zaten var. Model değişince `yuzBilgi(ord).merkez.z` yeniden okunup `ustZ` güncellenir (web `yuzZAl` karşılığı — `CamSistemi::associatifCoz(op)` yeni metodu).

---

## 2. İNTERAKTİF ŞEMA WIDGET'I (op penceresi içi)

Web `fiko-strateji-3d.component.ts` gömülü **tam 3D motor** kullanıyor (ayrı mini-sahne). Native'de mini Vulkan sahnesi pahalı; **ImGui DrawList ile izometrik 2D-şematik** çizim yeterli ve web'in ilettiği tüm bilgiyi taşır (blok/cep/limit/offset/toolaxis + hit-test). DrawList zaten kullanımda (`cam_simulasyon_penceresi.cpp:213`, `cam_takim_penceresi.cpp`).

**Widget imzası:** `bool camSemaCiz(CamOperasyon& op, CamSecimSistemi& secim, bool& degisti)` — `cam_strateji3d_widget.cpp` (YENİ). `geometriSekmesi` (cam_operasyon_penceresi.cpp) içinde araç şeridinin ALTINA çağrılır.

### 2.1 İzometrik projeksiyon (nokta → ekran)

Şema yerel 3B nokta `(x,y,z)` → widget-yerel 2B ekran. Web `cercevele` izometrik `kam.position=(d,-d,d)`; DrawList karşılığı sabit izometrik matris:
```
// birim izometrik (30° benzeri): eksen ekran vektörleri
ex = ( c, -c*0.5)    // +X sağ-aşağı
ey = (-c,  -c*0.5)   // +Y sol-aşağı   (c = ölçek)
ez = ( 0,  -c*0.9)   // +Z yukarı
scr(x,y,z) = merkez + x*ex + y*ey + z*ez
```
`c` = `min(widget_gen, widget_yuk) / (ext*3)`; `ext = max(10, bbox genişlik/yükseklik)` (web `_ext`, satır 76). merkez = widget ortası. Derinlik sıralaması: yüzleri z-ortalamasına göre arkadan öne çiz (painter).

### 2.2 Op tipine göre şema varyantı (web `sekilKategori` 173-182 → DrawList)

| Web kategori | Op tipleri | DrawList çizimi |
|---|---|---|
| `cep` | Pocketing | Kontur poligonu (dolgu koyu-yeşil `IM_COL32(20,105,47)`) + üst kontur çizgisi (seçilmişse sarı `0xffcc33`, değilse cyan `0x33d6ff`) + ada silindir işareti |
| `yuzey` | Facing | Sığ üst dilim (ince kutu üst yüzü) + kontur |
| `profil` | Contouring, CurveFollow | Kapalı kavite YOK; kontur boyunca duvar şeridi (kontur çizgisi + altına dikey çizgiler) + Limit1/Limit2 küre işaretleri (cyan/pembe) |
| `dairesel` | CircularMill | Daire (AddCircle) + merkez kontur torusu |
| `delik` | Axial (SpotDrill..) | Nokta konumlarında küçük daire+çarpı (delik ağzı) |
| `nokta` | PointToPoint | Nokta işaretleri (AddCircleFilled) |

Her varyantta ORTAK öğeler (aşağıda 2.3–2.5). Kontur yoksa web varsayılan L-profil şema çizer (satır 66) — native'de aynı: `op.geometri.konturlar` boşsa L-şekil placeholder (ayırt edici, "henüz seçilmemiş" göstergesi).

### 2.3 Ortak öğeler + rol hit-test (web `userData['rol']` → DrawList + InvisibleButton)

Web'de her tıklanabilir öğe `userData['rol']` taşır, raycast bulur. DrawList'te **her rol için görünmez ImGui butonu** (hit-test) + üstüne DrawList çizimi:

| Rol | Görsel | Hit alanı | Tık → |
|---|---|---|---|
| `kontur` | Üst kontur çizgisi (kalın, renkli) | Kontur bbox'u çevreleyen `InvisibleButton` VEYA çizgi-yakınlık | `secim.konturBaslat(op)` |
| `ada` | Kırmızı silindir işareti | işaret dairesi | `secim.adaBaslat(op)` |
| `nokta` | Delik/nokta işareti | işaret dairesi | `secim.noktaBaslat(op)` |
| `toolaxis` | Pembe ok (şaft+koni), yön=`op.takimYonu.yon` | ok bbox | `taGelismis()` (Tool Axis penceresi) |
| `limit1`/`limit2` | Cyan/pembe küre, kontur uçlarında | küre dairesi | `secim.noktaRefBaslat(op, …)` |
| `limitUst`/`limitAlt` | Mavi/pembe düzlem çerçevesi (üst/alt), köşe küreleri | çerçeve bbox | `secim.duzlemBaslat(op, ustZ/altZ ayarla, …)` |

**Hit-test tekniği:** widget alanı `ImGui::InvisibleButton("##sema", {gen,yuk})` ile kaplanır; `ImGui::IsItemHovered()` + `io.MousePos` alınır; her rolün ekran-şekline nokta-içinde/uzaklık testi (poligon-içi, daire, dikdörtgen) yapılır → hover rol vurgulanır (renk `lerp(beyaz,0.55)`, web `vurgula` 263-273), sol-tık ilgili `secim.xxxBaslat`. Çoklu InvisibleButton üst üste bindirme YOK — tek büyük buton + manuel hit-test (rol öncelik sırası: limit küreler > toolaxis > ada/nokta > kontur > offset).

### 2.4 Offset etiketleri (web 156-168 → DrawList, ÇİFT-TIK düzenle)

4 etiket dış kenarlarda (web dış=margin+ext*0.5):
```
ofsetUst   → +Y dış, z=ustZ,  "Üst <deger>"
ofsetKontur→ +X dış, z=orta,  "Kontür <deger>"
ofsetTaban → -Y dış, z=altZ,  "Taban <deger>"
ofsetCheck → -X dış, z=ustZ,  "Check <deger>"
```
Her etiket: DrawList `AddRectFilled` (koyu zemin) + `AddText` + merkeze bağlantı çizgisi (`AddLine` soluk). Hit: etiket dikdörtgeni. **Çift-tık** (`ImGui::IsMouseDoubleClicked(0)` + hover) → satır-içi düzenleme: `offsetDuzParam = f; degisti` (web 254, 717). Tek-tık offset'te ETKİSİZ (web: offset yalnız çift-tıkla düzenlenir, seçim modu başlatmaz). Düzenleme UI: widget altında `ImGui::InputDouble("##offset", &deger)` (Enter/blur → `op.geometri.ofsetXxx = deger; op.bayat=true`).

### 2.5 Takım ekseni oku (web 123-130)

Yön = `op.takimYonu.yon` (yoksa +Z). Şaft = izometrik çizgi (kalın pembe) `taBas + yon*taL`, uç = koni (küçük üçgen). Etiket "⊥ X/Y/Z/Özel" (web `eksenAd` 184). Tık → `taGelismis()` (Tool Axis penceresi — mevcut `camTakimEkseniPencereAc` varsa; yoksa bu dalgada TODO değil, ayrı komut).

### 2.6 Kamera/etkileşim

Web'de şema döndürülebilir (orbit). Native ImGui şema **sabit izometrik** (basitlik); istenirse widget üstünde sürükle → `ez/ex/ey` açısını döndür (opsiyonel, ilk dalgada sabit). Odak: web offset etiketleri her zaman okunur; native sprite yerine düz DrawList text (kameraya bakan zaten).

---

## 3. MAKRO 3D ÖNİZLEME (op penceresi Makro sekmesi)

Web `fiko-makro-3d.component.ts` gömülü motor + `makro3dNoktalar` (dialog 558-596) yol üretimi. Native: aynı **DrawList izometrik** widget (`camMakroCiz(CamMakro& m, bool ret, bool& degisti)` — `cam_makro3d_widget.cpp` YENİ), Makro sekmesinde (cam_operasyon_penceresi.cpp `makroDetay`) approach/retract/link tiplerinde çağrılır.

### 3.1 Yol noktası üretimi (web `makro3dNoktalar` 558-596 → C++ port)

LOCAL, engagement=origin. `yon = ret ? +1 : -1` (approach aşağı -Z). Hazır mod (`MakroMod::Hazir`) parametrelerini yansıt; custom mod adım dizisini uygula. Sonra toplam-delta çıkarılıp başlangıç `-toplam`'a alınır (dizi origin'de biter).

**Hareket tipi → segment (dünya birimi mm):**

| Tip | dx, dy, dz | Polyline |
|---|---|---|
| `Dikine`/`OnDelik`/`eksenel` | 0, 0, yon*L | tek çizgi |
| `Teget` | L, 0, 0 | tek çizgi |
| `Rampa` | L, 0, yon*tan(aci)*L | tek çizgi (açılı) |
| `Yay` | R, 0, yon*R | çeyrek yay örnekle (~12 nokta) |
| `Helis`/`helis` | 0,0,yon*L + sarmal | `N=18*tur` nokta: `x=cos(t*tur*2π)*R, y=sin(...)*R, z=yon*L*t`; `tur=ceil(L/(2π·R·tan(aci)))` |
| `Duzleme` | 0,0,yon*|hedefZ| | tek çizgi |

`aci` rad'a çevrilir (`*π/180`). Web formülleri satır 566-583 birebir.

### 3.2 Çizim (web `ciz` 65-109 → DrawList)

- Zemin ref: yarı-saydam kutu üst yüzü (izometrik dörtgen) + grid çizgileri (web `GridHelper`, satır 77) → DrawList `AddLine` ızgara.
- Yol: polyline `AddPolyline` (approach yeşil `0x34d399`, retract kırmızı `0xef4444` — web renk 221).
- Düğümler: her adım sonu `AddCircleFilled` (seçili sarı `0xffd24d` büyük, değilse beyaz). Hit: daire → tık `secAdim=adım` (web `adimSec` 149) + satır input'una odak.
- Ok: son segment yönünde koni üçgeni (`AddTriangleFilled`).
- Ölçü etiketleri: her adım sonuna metin (web `adimEtiketMetin` 609-616): `↧ <mm>` / `→ <mm>` / `<mm>·<°>` / `R<r>↻<mm>` / `Z<hedefZ>`. DrawList `AddText` + bağlantı çizgisi.

### 3.3 Düğüm sürükle → ölçü değiştir (web `dragBasla/dragHareket` 152-183)

Düğüme bas + sürükle → segment ekseni boyunca ekran-kayması → dünya birimi → ilgili ölçü (`m.mesafe` hazır / `adim.mesafe|hedefZ` custom) canlı artırılır (web `makro3dOlcu` 549-556). ImGui: `ImGui::IsItemActive()` + `io.MouseDelta`; segment ekseni ekran projeksiyonuna nokta-çarpımı → `dWorld`; `a.mesafe = max(0.1, a.mesafe + dWorld)`; `op.bayat=true`.

---

## 4. ANA ÜRÜN AĞACI ENTEGRASYONU (`cam_uretim_agaci.cpp` KALDIR)

Web'de CAM aktiviteleri ana ürün ağacında yaşar (`aktiviteEkle` deps). Native'de şu an AYRI `camUretimAgaciCiz` penceresi var → **KALDIRILIP** ana `Ürün Ağacı`'na (main.cpp 2384) CAM düğümleri sağlayıcıyla eklenir.

### 4.1 Sağlayıcı kaydı (web `aktiviteEkle` ≈ `AgacSaglayiciKaydi`)

`urunAgaciTopla` gibi bir CAM sağlayıcısı kaydedilir:
```cpp
// main.cpp kurulumda (satır 469 urunAgaciTopla yanına):
cekirdek.agac().ekle([&camSis](Cekirdek& c, std::vector<AgacDugum>& kok){
  camAgacTopla(c, camSis, kok);   // cam_urun_agaci.cpp (YENİ) — cam_uretim_agaci.cpp'nin yerini alır
});
```

### 4.2 `AgacDugum` üretimi — SANAL düğümler (varlik=VARLIK_YOK)

CAM op/part-op'lar ECS `Varlik` değil; `AgacDugum.varlik=VARLIK_YOK` (sanal). Etiket + kimlik `AgacDugum`'a taşınamıyor (yalnız `etiket/varlik/cocuklar` var) → **`AgacDugum` genişletilir** veya etikete kimlik gömülür. Öneri: `AgacDugum`'a opsiyonel `u32 camKimlik=0; u8 camTip=0` alanı EKLE (kayit.hpp:70) — sanal düğüm callback'i için (varlik=YOK olduğundan `cekirdek.nesne(v)` null döner, mevcut cizDugum bunu zaten `dug.etiket`'e düşürür, satır 2415).

Hiyerarşi (web/native CATIA):
```
🗂 Manufacturing Program            (camTip=Program)
 └ ⚙ Part Operation.1               (camTip=PartOp, camKimlik=pop.kimlik)
    ├ ✛ Machining Axis System (G54) (camTip=Axis)
    ├ ▦ Stok / Fikstür              (camTip=Stok)
    └ 🗂 (op listesi)
       └ ▣ Cep (Pocketing)          (camTip=Op, camKimlik=op.kimlik)
          ├ 🔧 T2 Parmak Freze Ø10  (camTip=Takim)
          └ 〰 Nc Programlar          (camTip=Yol)
```
(cam_uretim_agaci.cpp 138-204'teki hiyerarşi birebir; sağlayıcıya taşınır.)

### 4.3 cizDugum davranış bağlama (main.cpp 2399-2463)

Mevcut `cizDugum` sanal düğümde `n=nullptr, gv=nullptr` → etiket `dug.etiket`, ikon "▪". CAM düğümleri için `dug.camTip != 0` dallanması eklenir:
- **İkon/renk:** `camTip`'e göre (op durumu ⟳/✓/⏳ — cam_uretim_agaci.cpp `opDurumIkon`).
- **Çift-tık:** `if (dug.camTip==Op) camOperasyonPencereAc(dug.camKimlik);` `if (dug.camTip==PartOp) camParcaOpPencereAc(...)`. (Mevcut 2431 dblclick bloğuna `else if (dug.camTip)` eklenir; `secimiSigdir` yerine pencere açar.)
- **Sağ-tık:** `if (dug.camTip==Op) { ImGui::OpenPopup; opBaglamMenu(...) }` (cam_uretim_agaci.cpp 70-91 menüsü taşınır: Düzenle/Bastır/Takım Değiştir/Sil).
- **Seçim:** op düğümü → `camSis.seciliOp = kimlik` (govdeToparla sanal düğümde boş döner, sahne seçimi tetiklenmez — doğru).

### 4.4 Kaldırılacaklar

- `cam_uretim_agaci.cpp/.hpp` → içeriği `cam_urun_agaci.cpp` sağlayıcısına + main.cpp cizDugum dallarına taşınır, dosya silinir.
- main.cpp `camAgacAcik` bayrağı + `camUretimAgaciCiz` çağrısı kaldırılır; "Üretim Ağacı" komutu ana Ürün Ağacı'nı odaklar/açar.

---

## 5. UYGULAMA ADIMLARI (implementasyon ajanı — dosya dosya, sıralı)

1. **`motor/cam/include/fiko/cam/cam_secim.hpp` + `src/cam_secim.cpp` (YENİ):** `CamSecimSistemi` (1.3). `konturBaslat/adaBaslat/noktaBaslat/kenarBaslat/duzlemBaslat/noktaRefBaslat/toolaxisBaslat/stokKonturAta/tik/hover/bitir/beklenenKip/gorselle`. `BrepGovde::yuzKonturlari/yuzBilgi/kenarNoktalari` kullan (yeni brep fonksiyonu GEREKMEZ — hepsi mevcut). Olay yayınla (`CamSecimBasladi/Bitti/GeometriDegisti` — enum SONUNA).
2. **`CamSistemi` genişlet:** `CamSecimSistemi camSecim` üyesi + erişimci; `associatifCoz(op)` (ustZRef/altZRef/derinlikRef → `yuzBilgi.merkez.z` yeniden oku). Web `secimGorselle` karşılığı görsel düğüm yönetimi.
3. **`uygulama/fikocad/cam_strateji3d_widget.cpp/.hpp` (YENİ):** `camSemaCiz(op, camSecim, degisti)` — izometrik DrawList şema (2.1-2.6), rol hit-test → `camSecim.xxxBaslat`, offset çift-tık.
4. **`uygulama/fikocad/cam_makro3d_widget.cpp/.hpp` (YENİ):** `camMakroCiz(m, ret, degisti)` — makro yol DrawList (3.1-3.3), düğüm tık/sürükle.
5. **`cam_operasyon_penceresi.cpp` DÜZENLE:** `geometriSekmesi` — no-op butonları (satır 61-80) GERÇEK'e bağla (`camSecim.konturBaslat` vb.); araç şeridi altına `camSemaCiz` çağır; 🎯 Üst Z/Alt Z butonları → `camSecim.duzlemBaslat`. `makroDetay` — approach/retract/link'te `camMakroCiz` çağır. `Hesapla` butonu → `camSis.hesapla` (yol motoru; kapsam dışıysa TODO değil — mevcut hesap köprüsü).
6. **main.cpp DÜZENLE:**
   - `CamSecimSistemi camSecim{sahne, camSis, cekirdek.olaylar()};` kurulum.
   - fare.sol bloğu (2247): CAM tık kancası (1.3 snippet).
   - GPU pick filtresi (3593) + hover (3601): CAM aktifse `beklenenKip`.
   - ESC/sağ-tık: `camSecim.bitir()`.
   - Ağaç sağlayıcı kaydı (469 yanı) `camAgacTopla`; `cizDugum` (2399) CAM dalları (4.3).
7. **`AgacDugum` genişlet** (`kayit.hpp:70`): `u32 camKimlik=0; u8 camTip=0;`.
8. **`cam_urun_agaci.cpp/.hpp` (YENİ):** `camAgacTopla(c, cam, kok)` — hiyerarşi (4.2). **`cam_uretim_agaci.cpp/.hpp` SİL** + main.cpp çağrısı/`camAgacAcik` kaldır.
9. **Makro/plugin/olay:** `CamSecimSistemi` ve widget'lar cekirdek registry'den erişilebilir (Lua `fiko.cam.secim`, olaylar). Enum'lar SONUNA.
10. **Test:** `motor/cam/test/test_cam.cpp` — `CamSecimSistemi` kontur/nokta/duzlem/kenar/toolaxis seçim birim testleri (sahte gövde + yüz ordinali → beklenen op.geometri). Yol üretimi (`makro3dNoktalar` portu) sayısal doğrulama.

### PLACEHOLDER BIRAKILMAYACAK (uçtan uca zorunlu)
- Geometri sekmesi 5 butonu (Profil/Kontur, Kenar, Stok, Ada, Delik Merkezi) → gerçek seçim başlatır.
- Şema 8 rolü (kontur/ada/nokta/toolaxis/limit1/limit2/limitUst/limitAlt) → gerçek seçim modu.
- 4 offset etiketi çift-tık → gerçek düzenleme.
- 🎯 Üst Z / Alt Z / güvenlik / yaklaşma / düzleme-kadar → gerçek düzlem seçimi + associatif faceId.
- Makro widget düğüm tık → adım seç; sürükle → ölçü değiştir.
- Ağaç op düğümü çift-tık → op penceresi; sağ-tık → menü (Düzenle/Bastır/Takım/Sil).

---

## 6. WEB↔NATIVE FONKSİYON EŞLEME (hızlı referans)

| Web (`fiko-cam.yonetici.ts` / dialog) | Native |
|---|---|
| `camKonturSecBaslat` 689 | `CamSecimSistemi::konturBaslat` |
| `camNoktaSecBaslat` 688 | `noktaBaslat` |
| `camKenarSecBaslat` 659 | `kenarBaslat` |
| `camAdaSecBaslat` 670 | `adaBaslat` |
| `camDuzlemSecBaslat` 661 | `duzlemBaslat` |
| `camNoktaRefSecBaslat` 666 | `noktaRefBaslat` |
| `camTakimYonuYuzeySecBaslat` 691 | `toolaxisBaslat` |
| `camStokKonturAta` 673 | `stokKonturAta` (part-op stok kutusu) |
| `secTik` 745-811 | `tik` |
| `hoverTik` 720-744 | `hover` |
| `enYakinKenarGrup` 903-917 | kenar ekran-uzaklığı (GPU pick fallback) |
| `kenarlardanKontur` 918-950 | kenar zincir birleştirme |
| `yuzKonturAl`+`yuzKonturXY` 812-867 | `BrepGovde::yuzKonturlari(ord)` (TEK çağrı, mesh-boundary GEREKMEZ) |
| `secimGorselle` 630 | `gorselle` (salt-kenar düğüm) |
| `secimDurumBildir` 703 | `durum()` HUD |
| `takimYonuYuzey` (toolaxis) | `op.takimYonu{yon, Yuzey, yuzId, origin}` + `yuzBilgi.normal` |
| `stratejiRol` dialog 705-715 | şema widget rol dispatch |
| `offsetDuzenleAc/offsetKaydet` 717-718 | offset çift-tık InputDouble |
| `makro3dNoktalar` dialog 558-596 | `camMakro3d` yol port (3.1) |
| `makro3dAdimSec/makro3dOlcu` 544-556 | düğüm tık/sürükle (3.3) |
| `aktiviteEkle` (deps) | `AgacSaglayiciKaydi` + `camAgacTopla` |
| `cam_uretim_agaci.cpp` (ayrı pencere) | KALDIR → ana Ürün Ağacı sağlayıcı |
