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

3.2 KiB
Raw Blame History

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.tsxlocalClippingEnabled 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.