import { Eye, Grid3X3, Ruler, Trash2, Camera, LayoutGrid, Palette, Box, Move3D, Undo2, MousePointerClick, EyeOff, Focus, Download, Square, Scissors, Footprints } from 'lucide-react'; import { Slider } from '@/components/ui/slider'; import { Button } from '@/components/ui/button'; import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; import { useModelStore } from '@/stores/useModelStore'; import { ScaleSelector } from '@/components/ScaleSelector'; import { useCallback } from 'react'; import { toast } from 'sonner'; import { exportObjectsAsGLB } from '@/lib/exportSelectionGLB'; import * as THREE from 'three'; import { elementKey, sceneRef } from '@/components/three/ModelViewer'; const WIRE_COLORS = [ { label: 'Ciano (radiante)', value: '#00f3ff' }, { label: 'Vermelho', value: '#ef4444' }, { label: 'Verde', value: '#22c55e' }, { label: 'Azul', value: '#3b82f6' }, { label: 'Amarelo', value: '#eab308' }, { label: 'Laranja', value: '#f97316' }, { label: 'Branco', value: '#e2e8f0' }, { label: 'Cinza', value: '#8899aa' }, ]; export function ViewerControls() { const { opacity, setOpacity, renderMode, setRenderMode, measureMode, setMeasureMode, measurements, clearMeasurements, undoLastMeasurement, measurePoints, addScreenshot, showGrid, setShowGrid, wireframeColor, setWireframeColor, wireframeThickness, setWireframeThickness, edgeThresholdAngle, setEdgeThresholdAngle, positionMode, setPositionMode, walkMode, setWalkMode, activeModelId, models, selectionMode, setSelectionMode, selectedElementKeys, hiddenElementKeys, isolatedElementKeys, hideSelectedElements, isolateSelectedElements, showAllElements, clearElementSelection, cameraMode, setCameraMode, gridCalibMode, setGridCalibMode, setGridAutoFollow, sectionPanelOpen, setSectionPanelOpen, sectionEnabled, resetSection, } = useModelStore(); const sectionActive = sectionEnabled.x || sectionEnabled.y || sectionEnabled.z; const activeModel = models.find(m => m.id === activeModelId); const hasSelection = selectedElementKeys.size > 0; const hasHiddenOrIsolated = hiddenElementKeys.size > 0 || isolatedElementKeys !== null; const handleExportSelection = useCallback(async () => { if (!activeModel || selectedElementKeys.size === 0) return; const scene = sceneRef.current; if (!scene) { toast.error('Cena 3D não disponível'); return; } const objects: THREE.Object3D[] = []; const collect = (root: THREE.Object3D) => { const modelId = root.userData?.modelId as string | undefined; if (!modelId) { root.children.forEach(collect); return; } root.traverse((el) => { if (!el.userData?.ifcElement) return; if (selectedElementKeys.has(elementKey(modelId, el))) objects.push(el); }); }; collect(scene); if (objects.length === 0) { toast.error('Não foi possível localizar elementos selecionados. Use IFC para seleção persistente.'); return; } const base = activeModel.fileName.replace(/\.(glb|gltf|ifc|obj|stl)$/i, ''); await exportObjectsAsGLB(objects, `${base}_selecao_${objects.length}elem.glb`); toast.success(`GLB exportado com ${objects.length} elemento(s)`); }, [activeModel, selectedElementKeys]); const handleScreenshot = useCallback(() => { const canvas = document.querySelector('canvas'); if (!canvas) { toast.error('Canvas não encontrado'); return; } const dataUrl = canvas.toDataURL('image/png'); addScreenshot(dataUrl); toast.success('Screenshot capturado!'); }, [addScreenshot]); return (