import { useEffect, useMemo } from "react"; import CadViewer from "../CadViewer"; import DxfViewer from "../DxfViewer"; import ImplicitCadViewer from "../ImplicitCadViewer"; import { CircleAlert, X } from "lucide-react"; import { Alert, AlertDescription, AlertTitle } from "../ui/alert"; import { Button } from "../ui/button"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from "../ui/dropdown-menu"; import { ToggleGroup, ToggleGroupItem } from "../ui/toggle-group"; import AssemblyContextMenuItems from "./AssemblyContextMenuItems"; import { cn } from "@/ui/utils"; import { RENDER_FORMAT } from "@/workbench/constants"; import { isMeshRenderFormat, isRobotRenderFormat } from "cadjs/lib/fileFormats"; import { CAMERA_PROJECTION, normalizeCameraProjection } from "cadjs/lib/displaySettings"; import { VIEWER_SCENE_SCALE } from "cadjs/lib/viewer/sceneScale"; import { VIEWER_PICK_MODE } from "cadjs/lib/viewer/constants"; import { useStepAnimationSnapshot } from "@/workbench/stepAnimationStore"; import { viewerPickModeForRenderPane } from "@/workbench/viewerPickMode"; const EMPTY_LIST = Object.freeze([]); const VIEWPORT_ISSUE_META = Object.freeze({ error: { label: "Error", borderClassName: "border-destructive/45", iconClassName: "border-destructive/45 bg-destructive/10 text-destructive dark:text-red-300", labelClassName: "text-destructive dark:text-red-300" }, warning: { label: "Warning", borderClassName: "border-amber-500/45", iconClassName: "border-amber-500/55 bg-amber-500/10 text-amber-500 dark:text-amber-300", labelClassName: "text-amber-500 dark:text-amber-300" } }); function viewportInsetPx(value) { const numericValue = Number(value); return Number.isFinite(numericValue) && numericValue > 0 ? numericValue : 0; } function viewportIssueMetaForAlert(alert) { return alert?.severity === "warning" ? VIEWPORT_ISSUE_META.warning : VIEWPORT_ISSUE_META.error; } function viewerContextMenuAnchorStyle(menu, viewportFrameInsets) { if (!menu) { return null; } const margin = 8; const viewportWidth = typeof window !== "undefined" ? window.innerWidth : 0; const viewportHeight = typeof window !== "undefined" ? window.innerHeight : 0; const minX = viewportInsetPx(viewportFrameInsets?.left) + margin; const minY = viewportInsetPx(viewportFrameInsets?.top) + margin; const maxX = viewportWidth > 0 ? Math.max(minX, viewportWidth - viewportInsetPx(viewportFrameInsets?.right) - margin) : Number(menu.x) || minX; const maxY = viewportHeight > 0 ? Math.max(minY, viewportHeight - viewportInsetPx(viewportFrameInsets?.bottom) - margin) : Number(menu.y) || minY; const x = Math.min(Math.max(Number(menu.x) || minX, minX), maxX); const y = Math.min(Math.max(Number(menu.y) || minY, minY), maxY); return { position: "fixed", left: `${x}px`, top: `${y}px`, width: "1px", height: "1px" }; } function DxfViewModeControl({ value, threeDimensionalAvailable = false, onChange }) { const normalizedValue = value === "3d" && threeDimensionalAvailable ? "3d" : "2d"; return (
{ if (!nextValue) { return; } if (nextValue === "3d" && !threeDimensionalAvailable) { return; } onChange?.(nextValue); }} className="grid h-7 w-[5.5rem] grid-cols-2" aria-label="DXF view mode" > 2D 3D
); } function ViewerContextMenu({ menu, positionStyle, onClose, onCopyReference, onSelect, onFocus, onExitAllIsolate, onHideOther, onHideAll, onHide, onReveal, onResetZoom, onZoomToFit, onExpandSelected, onCollapseSelected, onExpandAll, onCollapseAll }) { if (!menu || !positionStyle) { return null; } const itemClassName = "text-xs"; const handleAction = (action) => { action?.(menu); onClose?.(); }; const selected = menu.selected === true; const hidden = menu.hidden === true; const focused = menu.focused === true; return ( { if (!nextOpen) { onClose?.(); } }} > ) : null} {!previewMode && urdfPosePickerActive ? (
{urdfPosePickerPrompt}
) : null} {!previewMode && ctaMode && !stepUpdateInProgress && !topologySelectionPending && !topologySelectionUnavailable && !topologySelectionDeferred ? (
) : null} ); }