private void MakePasteOffsetUnique(VFXViewController viewController, SerializableGraph serializableGraph) { // look if pasting there will result in the first element beeing exactly on top of other while (true) { bool foundSamePosition = false; if (serializableGraph.contexts != null && serializableGraph.contexts.Length > 0) { foreach (var existingContext in viewController.graph.children.OfType <VFXContext>()) { if ((serializableGraph.contexts[0].node.position + pasteOffset - existingContext.position).sqrMagnitude < 1) { foundSamePosition = true; break; } } } else if (serializableGraph.operators != null && serializableGraph.operators.Length > 0) { foreach (var existingSlotContainer in viewController.graph.children.Where(t => t is IVFXSlotContainer)) { if ((serializableGraph.operators[0].position + pasteOffset - existingSlotContainer.position).sqrMagnitude < 1) { foundSamePosition = true; break; } } } else if (serializableGraph.parameters != null && serializableGraph.parameters.Length > 0 && serializableGraph.parameters[0].nodes.Length > 0) { foreach (var existingSlotContainer in viewController.graph.children.Where(t => t is IVFXSlotContainer)) { if ((serializableGraph.parameters[0].nodes[0].position + pasteOffset - existingSlotContainer.position).sqrMagnitude < 1) { foundSamePosition = true; break; } } } else if (serializableGraph.stickyNotes != null && serializableGraph.stickyNotes.Length > 0) { foreach (var stickyNote in viewController.stickyNotes) { if ((serializableGraph.stickyNotes[0].position.position + pasteOffset - stickyNote.position.position).sqrMagnitude < 1) { foundSamePosition = true; break; } } } else if (serializableGraph.groupNodes != null && serializableGraph.groupNodes.Length > 0) { foreach (var gn in viewController.groupNodes) { if ((serializableGraph.groupNodes[0].infos.position.position + pasteOffset - gn.position.position).sqrMagnitude < 1) { foundSamePosition = true; break; } } } if (foundSamePosition) { pasteOffset += Vector2.one * 30; } else { break; } } }
void PasteAll(VFXViewController viewController, Vector2 center, ref SerializableGraph serializableGraph, VFXView view, VFXGroupNodeController groupNode, List <VFXNodeController> nodesInTheSameOrder) { newControllers.Clear(); m_NodesInTheSameOrder = new VFXNodeID[serializableGraph.controllerCount]; var graph = viewController.graph; pasteOffset = (serializableGraph.bounds.width > 0 && serializableGraph.bounds.height > 0) ? center - serializableGraph.bounds.center : Vector2.zero; MakePasteOffsetUnique(viewController, serializableGraph); // Can't paste context within subgraph block/operator if (viewController.model.visualEffectObject is VisualEffectSubgraphOperator || viewController.model.visualEffectObject is VisualEffectSubgraphBlock) { if (serializableGraph.contexts != null) { var count = serializableGraph.contexts.Count(); if (count != 0) { Debug.LogWarningFormat("{0} context{1} been skipped during the paste operation. Contexts aren't available in this kind of subgraph.", count, count > 1 ? "s have" : " has"); } } } else { PasteContexts(viewController, ref serializableGraph); } PasteOperators(viewController, ref serializableGraph); PasteParameters(viewController, ref serializableGraph); // Create controllers for all new nodes viewController.LightApplyChanges(); // Register all nodes for usage in groupNodes and edges RegisterContexts(viewController); RegisterOperators(viewController); RegisterParameterNodes(viewController); VFXUI ui = viewController.graph.UIInfos; firstCopiedGroup = -1; firstCopiedStickyNote = ui.stickyNoteInfos != null ? ui.stickyNoteInfos.Length : 0; //Paste Everything else PasteGroupNodes(ref serializableGraph, ui); PasteStickyNotes(ref serializableGraph, ui); PasteDatas(ref serializableGraph); // TODO Data settings should be pasted at context creation. This can lead to issues as blocks are added before data is initialized PasteDataEdges(ref serializableGraph); PasteFlowEdges(ref serializableGraph); // Create all ui based on model viewController.LightApplyChanges(); if (nodesInTheSameOrder != null) { nodesInTheSameOrder.Clear(); nodesInTheSameOrder.AddRange(m_NodesInTheSameOrder.Select(t => t.model == null ? null : viewController.GetNodeController(t.model, t.id))); } if (view != null) { SelectCopiedElements(view, groupNode); } }
private void PasteParameters(VFXViewController viewController, ref SerializableGraph serializableGraph) { newParameters.Clear(); if (serializableGraph.parameters != null) { foreach (var parameter in serializableGraph.parameters) { // if we have a parameter with the same name use it else create it with the copied data VFXParameter p = viewController.graph.children.OfType <VFXParameter>().FirstOrDefault(t => t.GetInstanceID() == parameter.originalInstanceID); if (p == null) { Type type = parameter.value.type; VFXModelDescriptorParameters desc = VFXLibrary.GetParameters().FirstOrDefault(t => t.model.type == type); if (desc != null) { p = viewController.AddVFXParameter(Vector2.zero, desc); p.value = parameter.value.Get(); p.valueFilter = parameter.valueFilter; if (parameter.valueFilter == VFXValueFilter.Range) { p.min = parameter.min.Get(); p.max = parameter.max.Get(); } else if (parameter.valueFilter == VFXValueFilter.Enum) { p.enumValues = parameter.enumValue.ToList(); } p.SetSettingValue("m_Exposed", parameter.exposed); if (viewController.model.visualEffectObject is VisualEffectSubgraphOperator) { p.isOutput = parameter.isOutput; } p.SetSettingValue("m_ExposedName", parameter.name); // the controller will take care or name unicity later p.tooltip = parameter.tooltip; } } if (p == null) { newParameters.Add(new KeyValuePair <VFXParameter, List <int> >(null, null)); continue; } var newParameterNodes = new List <int>(); foreach (var node in parameter.nodes) { int nodeIndex = p.AddNode(node.position + pasteOffset); var nodeModel = p.nodes.LastOrDefault(t => t.id == nodeIndex); nodeModel.expanded = !node.collapsed; nodeModel.expandedSlots = AllSlots(p.outputSlots).Where(t => node.expandedOutput.Contains(t.path)).ToList(); m_NodesInTheSameOrder[node.indexInClipboard] = new VFXNodeID(p, nodeModel.id); newParameterNodes.Add(nodeIndex); } newParameters.Add(new KeyValuePair <VFXParameter, List <int> >(p, newParameterNodes)); } } }
void PasteBlocks(VFXView view, ref SerializableGraph serializableGraph) { var selectedContexts = view.selection.OfType <VFXContextUI>(); var selectedBlocks = view.selection.OfType <VFXBlockUI>(); VFXBlockUI targetBlock = null; VFXContextUI targetContext = null; if (selectedBlocks.Count() > 0) { targetBlock = selectedBlocks.OrderByDescending(t => t.context.controller.model.GetIndex(t.controller.model)).First(); targetContext = targetBlock.context; } else if (selectedContexts.Count() == 1) { targetContext = selectedContexts.First(); } else { Debug.LogError(m_BlockPasteError.text); return; } VFXContext targetModelContext = targetContext.controller.model; int targetIndex = -1; if (targetBlock != null) { targetIndex = targetModelContext.GetIndex(targetBlock.controller.model) + 1; } var newBlocks = new HashSet <VFXBlock>(); newControllers.Clear(); foreach (var block in serializableGraph.operatorsOrBlocks) { Node blk = block; VFXBlock newBlock = PasteAndInitializeNode <VFXBlock>(view.controller, ref blk); if (targetModelContext.AcceptChild(newBlock, targetIndex)) { newBlocks.Add(newBlock); targetModelContext.AddChild(newBlock, targetIndex, false); // only notify once after all blocks have been added targetIndex++; } } targetModelContext.Invalidate(VFXModel.InvalidationCause.kStructureChanged); //TODO fill infos.indexToController for when external links will be optionally copied. view.ClearSelection(); foreach (var uiBlock in targetContext.Query().OfType <VFXBlockUI>().Where(t => newBlocks.Contains(t.controller.model)).ToList()) { view.AddToSelection(uiBlock); } }