import { scene } from '@dsf/core/global' import { contains, distinct, group } from './array-helper' import { getRoot, isFigure } from './node-helper' import { getPaneNodeEditor, getParametersPane, getParametersPaneNodeEditor } from './pane-helper' import { startsWith } from './string-helper' export const getSelectedOf = (typeName: string): DzNode[] => { let nodes: DzNode[] = [] for (let node of scene.getSelectedNodeList()) { if (!node || !node.inherits(typeName)) continue nodes.push(node) } return nodes } export const getSelectedNode = (): DzNode | null => { if (scene.getNumSelectedNodes() === 0) return null return scene.getPrimarySelection() } export const getTopParent = (node: DzNode): DzNode => { var parent = node.getNodeParent(); return parent ? getTopParent(parent) : node; } export const getParentFigure = (node: DzNode): DzSkeleton | null => { if (!node) return null; if (isFigure(node)) return node as DzSkeleton; return getParentFigure(node.getNodeParent()); } export const getNodes = (): DzNode[] => { return scene.getNodeList() } export const getRootNodes = (): DzNode[] => { return getNodes().map(n => getRoot(n)).filter(n => n !== null) } export const getFigures = (): DzSkeleton[] => { return distinct(getNodes().map(n => n.getSkeleton?.()), (n => n?.getLabel().valueOf())).filter(n => n !== null) } /** * Get the selected figure * @returns the figure skeleton, or null if there is no current selection or the selected node is not part of a figure */ export const getSelectedFigure = (): DzSkeleton | null => { return getSelectedNode()?.getSkeleton?.() ?? null } /** * Given the selected nodes in the scene, return the figures they are part of * @returns the selected figures */ export const getSelectedFigures = (): DzSkeleton[] => { let nodes: DzSkeleton[] = [] for (let node of scene.getSelectedNodeList()) { let skeleton = node.getSkeleton?.() if (!skeleton || contains(nodes, node)) continue nodes.push(skeleton) } return nodes } export const getSelectedNodes = (): DzNode[] => { return scene.getSelectedNodeList() } export const getSelectedRoot = (): DzNode | null => { return getRoot(getSelectedNode()) } export const getSelectedRoots = (): DzNode[] => { return distinct(getSelectedNodes().map(n => getRoot(n))).filter(n => n !== null) as DzNode[] } export const getSelectedProperties = (): DzProperty[] => { return getParametersPane()?.getNodeEditor()?.getPropertySelections(true) ?? [] } export const getSelectedNumericProperties = (): (DzFloatProperty | DzIntProperty | DzBoolProperty)[] => { return getParametersPane()?.getNodeEditor()?.getPropertySelections(true).map(p => p as unknown as DzFloatProperty | DzIntProperty | DzBoolProperty) ?? [] } export const getSelectedPropertiesOfType = (type: string): TProperty[] => { return getSelectedProperties().filter(p => p.inherits(type)) as TProperty[] } export const getSelectedPropertiesOfTypes = (types: string[]): TProperty[] => { return getSelectedProperties().filter(p => types.some(type => p.inherits(type))) as TProperty[] } export const getSelectedPropertyGroups = (pane?: DzAbstractNodeEditorPane): string[] => { var propertyGroups: string[] = []; var paneNodeEditor = pane ? getPaneNodeEditor(pane) : getParametersPaneNodeEditor(); var selectedProperties = paneNodeEditor?.getPropertySelections(true) if (selectedProperties.length == 0) selectedProperties = paneNodeEditor?.getPropertySelections(false) if (selectedProperties.length == 0) return propertyGroups var pathsGroup = group(selectedProperties, p => p.getPath().valueOf().substr(1) + "/") propertyGroups = Object.keys(pathsGroup) return propertyGroups } export const clearSelection = () => { for (let node of scene.getSelectedNodeList()) { node.select(false) } } export const currentTime = (): DzTime => { return scene.getTime() } /** * @returns the current frame number (0-based) */ export const getCurrentFrame = (): number => { return scene.getTime().valueOf() / scene.getTimeStep().valueOf() } export const getEndFrame = (): number => { return scene.getAnimRange().end.valueOf() / scene.getTimeStep().valueOf() } /** * @deprecated Use getEndFrame * @returns the last frame number (0-based) */ export const getLastFrame = (): number => { return scene.getAnimRange().end.valueOf() / scene.getTimeStep().valueOf() } export const timeToFrame = (time: DzTime): number => { return time.valueOf() / scene.getTimeStep().valueOf() } export const frameToTime = (frame: number): DzTime => { return new DzTime(scene.getTimeStep().valueOf() * frame) } export const collectSceneNodeIds = (): number[] => { const ids: number[] = [] for (let i = 0; i < Scene.getNumNodes(); i++) { ids.push(Scene.getNode(i).elementID) } return ids } export const getNodesAddedAfter = (beforeIds: number[]): DzNode[] => { const nodes: DzNode[] = [] for (let i = 0; i < Scene.getNumNodes(); i++) { const node = Scene.getNode(i) if (beforeIds.indexOf(node.elementID) < 0) nodes.push(node) } return nodes } export const removeNodesByNameOrLabelPrefix = (prefix: string): number => { const nodes: DzNode[] = [] for (let i = 0; i < Scene.getNumNodes(); i++) { const node = Scene.getNode(i) if (startsWith(String(node.getName()), prefix) || startsWith(String(node.getLabel()), prefix)) { nodes.push(node) } } for (let i = 0; i < nodes.length; i++) { Scene.removeNode(nodes[i]) } return nodes.length }