Files
SteelXR/.lovable/plan.md
T
gpt-engineer-app[bot] 649d4ecdca Changes
Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com>
2026-05-24 22:52:30 +00:00

48 lines
3.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Objetivo
Adicionar uma ferramenta de **corte de seção** (clipping planes) nos eixos X, Y e Z — padrão em viewers IFC/BIM. O usuário move sliders por eixo e a peça vai sendo cortada/revelada em tempo real. Implementada como **janela pop-up flutuante** sobre o viewer, com controle de opacidade da própria janela. Sem presets persistidos.
## UX
### Botões na barra `ViewerControls`
- **"Cortes"** (ícone `Scissors`) — abre/fecha a janela pop-up. O estado dos cortes é independente da janela: fechar não reseta nada.
- **Lixeira** ao lado, só fica habilitada quando há pelo menos um eixo de corte ativo. Clicar = `resetSection()` (desliga e zera os 3 eixos). Único caminho para zerar.
- Indicador visual no botão "Cortes" quando há corte ativo (badge ou variante `default`).
### Pop-up (componente `SectionCutPanel`)
- Janela flutuante sobre o viewer (canto superior-direito da área 3D), arrastável pelo header. Não-modal.
- Estilo: `bg-card/X` + `backdrop-blur`, borda industrial, font-mono.
- **Header**: título "Cortes de Seção", slider de **opacidade da janela** (20%100%, default 90%), botão fechar (X).
- **3 blocos idênticos** para X / Y / Z, cada um com controle individual:
- Switch on/off do eixo.
- Switch "Inverter" (flip do lado mantido).
- Slider do nível de corte mapeado ao bbox mundial da peça ativa naquele eixo, valor em mm.
- Mini-botões: **Min** · **Centro** · **Max** para saltar a posição.
- Botão **"Recalcular limites"** (re-amostra o bbox depois de calibração/fine-tuning).
- Sem botões de salvar/memória.
- Fechar a janela apenas oculta os controles. Reabrir mostra exatamente o estado dos cortes que o usuário deixou.
## Comportamento técnico
- `gl.localClippingEnabled = true` no `onCreated` do `<Canvas>`.
- Novos campos em `useModelStore` (não persistidos):
- `sectionEnabled: { x: boolean; y: boolean; z: boolean }`
- `sectionInvert: { x: boolean; y: boolean; z: boolean }`
- `sectionLevel: { x: number; y: number; z: number }` (em metros, mundo)
- `sectionPanelOpen: boolean`
- `sectionPanelOpacity: number` (0.21)
- Setters por eixo + `resetSection()` (zera enabled, invert e leva level ao centro do bbox).
- Helper `hasActiveSection()` derivado de `sectionEnabled`.
- Novo componente `<SectionClippingApplier>` montado dentro do `<Canvas>`:
- Mantém 3 `THREE.Plane` reutilizáveis. A cada mudança nos campos do store, atualiza `plane.normal` (com sinal flipado se `invert`) e `plane.constant = -level` (axis-aligned, mundo).
- Aplica `material.clippingPlanes = ativos` em cada `Mesh` dos grupos registrados em `modelTransforms`. Restaura `[]` ao desligar todos os eixos.
- Limites dos sliders: bbox mundial agregado dos `getAllModelLocalGroups()`. Calculado quando o painel abre e quando o usuário aciona "Recalcular limites".
## Arquivos afetados
- `src/stores/useModelStore.ts` — novos campos e setters de seção + painel.
- `src/components/three/ModelViewer.tsx``localClippingEnabled` no GL; monta `<SectionClippingApplier>`.
- `src/components/SectionCutPanel.tsx` (novo) — janela pop-up flutuante com 3 sliders, switches, opacidade.
- `src/components/ViewerControls.tsx` — botão "Cortes" + lixeira condicional.
- `src/pages/Viewer.tsx` — monta `<SectionCutPanel />` na área do viewer.