Ejemplo n.º 1
0
 public void ConvertToSubgraphOperator(VFXView sourceView, IEnumerable <Controller> controllers, Rect rect)
 {
     this.m_Rect = rect;
     Init(sourceView, controllers);
     if (!CreateUniqueSubgraph("SubgraphOperator", VisualEffectSubgraphOperator.Extension, VisualEffectAssetEditorUtility.CreateNew <VisualEffectSubgraphOperator>))
     {
         return;
     }
     CopyPasteNodes();
     m_SourceNode = ScriptableObject.CreateInstance <VFXSubgraphOperator>();
     PostSetupNode();
     m_SourceControllersWithBlocks = m_SourceControllers.Concat(m_SourceControllers.OfType <VFXContextController>().SelectMany(t => t.blockControllers));
     TransferEdges();
     TransfertOperatorOutputEdges();
     Uninit();
 }
Ejemplo n.º 2
0
 bool ValidateVFXModel(VFXModel model, VFXModel expectedParent)
 {
     if (model == null)
     {
         LogError("Model error : null. in parent:" + GetVFXModelDesc(expectedParent));
         return(false);
     }
     if (model.GetParent() != expectedParent)
     {
         LogError("Model error : wrong parent. expected:" + GetVFXModelDesc(expectedParent) + " actual:" + GetVFXModelDesc(model.GetParent()));
     }
     if (!(model is VFXSlot) && model.GetGraph() != m_Graph)
     {
         LogError("Model error : " + GetVFXModelDesc(model) + " wrong graph. expected:" + GetVFXModelDesc(m_Graph) + " actual:" + GetVFXModelDesc(model.GetParent()));
     }
     return(true);
 }
Ejemplo n.º 3
0
        NodeID CopyNode(ref Node node, VFXModel model, uint index)
        {
            // Copy node infos
            node.position = model.position;
            node.type     = model.GetType();
            node.flags    = 0;
            if (model.collapsed)
            {
                node.flags = Node.Flags.Collapsed;
            }
            if (model.superCollapsed)
            {
                node.flags = Node.Flags.SuperCollapsed;
            }

            uint id = 0;

            if (model is VFXOperator)
            {
                id = OperatorFlag;
            }
            else if (model is VFXContext)
            {
                id = ContextFlag;
            }

            id |= (uint)index;

            //Copy settings value
            CopyModelSettings(ref node.settings, model);

            var inputSlots = (model as IVFXSlotContainer).inputSlots;

            node.inputSlots = new Property[inputSlots.Count];
            for (int i = 0; i < inputSlots.Count; i++)
            {
                node.inputSlots[i].name  = inputSlots[i].name;
                node.inputSlots[i].value = new VFXSerializableObject(inputSlots[i].property.type, inputSlots[i].value);
            }

            node.expandedInputs  = AllSlots(inputSlots).Where(t => !t.collapsed).Select(t => t.path).ToArray();
            node.expandedOutputs = AllSlots((model as IVFXSlotContainer).outputSlots).Where(t => !t.collapsed).Select(t => t.path).ToArray();

            return(id);
        }
Ejemplo n.º 4
0
        void PasteNode(VFXModel model, Vector2 center, Rect bounds, ref Node node)
        {
            var offset = node.position - bounds.min;

            model.position = center + offset;

            PasteModelSettings(model, node.settings, model.GetType());

            model.Invalidate(VFXModel.InvalidationCause.kSettingChanged);

            var slotContainer = model as IVFXSlotContainer;
            var inputSlots    = slotContainer.inputSlots;

            for (int i = 0; i < node.inputSlots.Length && i < inputSlots.Count; ++i)
            {
                if (inputSlots[i].name == node.inputSlots[i].name)
                {
                    inputSlots[i].value = node.inputSlots[i].value.Get();
                    if (inputSlots[i].spaceable)
                    {
                        inputSlots[i].space = node.inputSlots[i].space;
                    }
                }
            }

            if ((node.flags & Node.Flags.Collapsed) == Node.Flags.Collapsed)
            {
                model.collapsed = true;
            }

            if ((node.flags & Node.Flags.SuperCollapsed) == Node.Flags.SuperCollapsed)
            {
                model.superCollapsed = true;
            }

            foreach (var slot in AllSlots(slotContainer.inputSlots))
            {
                slot.collapsed = !node.expandedInputs.Contains(slot.path);
            }
            foreach (var slot in AllSlots(slotContainer.outputSlots))
            {
                slot.collapsed = !node.expandedOutputs.Contains(slot.path);
            }
        }
Ejemplo n.º 5
0
        void ValidateSlotContainer(IVFXSlotContainer slotContainer, VFXModel expectedParent)
        {
            if (!ValidateVFXModel(slotContainer as VFXModel, expectedParent))
            {
                return;
            }

            ValidateSlots(slotContainer.inputSlots, slotContainer);
            ValidateSlots(slotContainer.outputSlots, slotContainer);

            if (slotContainer is VFXContext)
            {
                VFXContext context = slotContainer as VFXContext;
                foreach (var block in context.children)
                {
                    ValidateSlotContainer(block, context);
                }
            }
        }
Ejemplo n.º 6
0
        protected internal override void Invalidate(VFXModel model, InvalidationCause cause)
        {
            base.Invalidate(model, cause);

            if (cause == InvalidationCause.kSettingChanged &&
                !validSmoothnessSources.Contains(smoothnessSource))
            {
                var fallbackSmoothness = SmoothnessSource.None;
                if (smoothnessSource == SmoothnessSource.MetallicAlpha && validSmoothnessSources.Contains(SmoothnessSource.SpecularAlpha))
                {
                    fallbackSmoothness = SmoothnessSource.SpecularAlpha;
                }
                if (smoothnessSource == SmoothnessSource.SpecularAlpha && validSmoothnessSources.Contains(SmoothnessSource.MetallicAlpha))
                {
                    fallbackSmoothness = SmoothnessSource.MetallicAlpha;
                }

                SetSettingValue(nameof(smoothnessSource), fallbackSmoothness);
            }
        }
Ejemplo n.º 7
0
        public void ChangeParent()
        {
            VFXModel modelA0 = ScriptableObject.CreateInstance <VFXModelA>();
            VFXModel modelA1 = ScriptableObject.CreateInstance <VFXModelA>();
            VFXModel modelB  = ScriptableObject.CreateInstance <VFXModelB>();

            s_logs.Clear();
            modelA0.AddChild(modelB);
            modelA1.AddChild(modelB);

            Assert.AreEqual(0, modelA0.GetNbChildren());
            Assert.AreEqual(1, modelA1.GetNbChildren());
            Assert.AreEqual(modelA1, modelB.GetParent());

            Assert.AreEqual(6, s_logs.Count);
            Assert.AreEqual("OnAdded VFXModelB", s_logs[0]);
            Assert.AreEqual("OnInvalidate VFXModelA kStructureChanged", s_logs[1]);
            Assert.AreEqual("OnRemoved VFXModelB", s_logs[2]);
            Assert.AreEqual("OnInvalidate VFXModelA kStructureChanged", s_logs[3]);
            Assert.AreEqual("OnAdded VFXModelB", s_logs[4]);
            Assert.AreEqual("OnInvalidate VFXModelA kStructureChanged", s_logs[5]);
        }
Ejemplo n.º 8
0
        void PasteNode(VFXModel model, ref Node node)
        {
            model.position = node.position + pasteOffset;

            PasteModelSettings(model, node.settings, model.GetType());

            model.Invalidate(VFXModel.InvalidationCause.kSettingChanged);

            var slotContainer = model as IVFXSlotContainer;
            var inputSlots    = slotContainer.inputSlots;

            for (int i = 0; i < node.inputSlots.Length; ++i)
            {
                if (inputSlots[i].name == node.inputSlots[i].name)
                {
                    inputSlots[i].value = node.inputSlots[i].value.Get();
                }
            }

            if ((node.flags & Node.Flags.Collapsed) == Node.Flags.Collapsed)
            {
                model.collapsed = true;
            }

            if ((node.flags & Node.Flags.SuperCollapsed) == Node.Flags.SuperCollapsed)
            {
                model.superCollapsed = true;
            }

            foreach (var slot in AllSlots(slotContainer.inputSlots))
            {
                slot.collapsed = !node.expandedInputs.Contains(slot.path);
            }
            foreach (var slot in AllSlots(slotContainer.outputSlots))
            {
                slot.collapsed = !node.expandedOutputs.Contains(slot.path);
            }
        }
Ejemplo n.º 9
0
        public void IncremenentGraphUndoRedoState(VFXModel model, VFXModel.InvalidationCause cause)
        {
            if (cause == VFXModel.InvalidationCause.kParamChanged)
            {
                if (model is VFXSlot) // model not beeing a VFXSlot means it is a subgraph reporting a value change
                {
                    if (m_graphUndoStack != null)
                    {
                        m_graphUndoStack.AddSlotDelta(model as VFXSlot);
                    }
                }
                return;
            }

            if (cause == VFXModel.InvalidationCause.kExpressionInvalidated ||   // Ignore invalidation which doesn't modify model
                cause == VFXModel.InvalidationCause.kExpressionGraphChanged)
            {
                return;
            }

            if (m_reentrant)
            {
                m_reentrant = false;
                throw new InvalidOperationException("Reentrant undo/redo, this is not supposed to happen!");
            }

            if (m_graphUndoStack != null)
            {
                if (m_graphUndoStack == null)
                {
                    Debug.LogError("Unexpected IncrementGraphState (not initialize)");
                    return;
                }

                m_graphUndoStack.IncrementGraphState();
            }
        }
 public VFXUnifiedOperatorControllerBase(VFXModel model, VFXViewController viewController) : base(model, viewController)
 {
 }
Ejemplo n.º 11
0
            public void ConvertToSubgraphBlock(VFXView sourceView, IEnumerable <Controller> controllers, Rect rect)
            {
                this.m_Rect = rect;
                Init(sourceView, controllers);
                if (!CreateUniqueSubgraph("SubgraphBlock", VisualEffectSubgraphBlock.Extension, VisualEffectAssetEditorUtility.CreateNew <VisualEffectSubgraphBlock>))
                {
                    return;
                }

                m_SourceControllers.RemoveAll(t => t is VFXContextController); // Don't copy contexts
                CopyPasteNodes();

                m_SourceBlockControllers = m_SourceControllers.OfType <VFXBlockController>().OrderBy(t => t.index).ToList();

                VFXContextController sourceContextController = m_SourceBlockControllers.First().contextController;

                object copyData = VFXCopy.CopyBlocks(m_SourceBlockControllers);

                var targetContext = m_TargetController.graph.children.OfType <VFXBlockSubgraphContext>().FirstOrDefault();

                if (targetContext == null)
                {
                    targetContext = ScriptableObject.CreateInstance <VFXBlockSubgraphContext>();
                    m_TargetController.graph.AddChild(targetContext);
                }
                m_TargetController.LightApplyChanges();
                targetContext.position = sourceContextController.position;
                targetContext.SetSettingValue("m_SuitableContexts", (VFXBlockSubgraphContext.ContextType)m_SourceBlockControllers.Select(t => t.model.compatibleContexts).Aggregate((t, s) => t & s));
                m_TargetBlocks = new List <VFXBlockController>();

                VFXPaste.PasteBlocks(m_TargetController, copyData, targetContext, 0, m_TargetBlocks);

                var otherSourceControllers = m_SourceControllers.OfType <VFXNodeController>().Where(t => !(t is VFXBlockController)).ToList();

                //Create lost links between nodes and blocks
                foreach (var edge in m_SourceController.dataEdges.Where(t => otherSourceControllers.Contains(t.output.sourceNode) && m_SourceBlockControllers.Contains(t.input.sourceNode)))
                {
                    var outputNode = m_TargetControllers[m_SourceControllers.IndexOf(edge.output.sourceNode)];
                    var output     = outputNode.outputPorts.First(t => t.path == edge.output.path);

                    var inputBlock = m_TargetBlocks[m_SourceBlockControllers.IndexOf(edge.input.sourceNode as VFXBlockController)];
                    var input      = inputBlock.inputPorts.First(t => t.path == edge.input.path);

                    m_TargetController.CreateLink(input, output);
                }

                var sourceBlock = ScriptableObject.CreateInstance <VFXSubgraphBlock>();

                m_SourceNode = sourceBlock;
                sourceContextController.model.AddChild(m_SourceNode, m_SourceBlockControllers.Select(t => t.index).Min());
                sourceContextController.ApplyChanges();
                m_SourceNodeController = sourceContextController.blockControllers.First(t => t.model == m_SourceNode);
                PostSetup();
                m_SourceNode.SetSettingValue("m_Subgraph", m_TargetSubgraph);
                m_SourceNodeController.ApplyChanges();

                var targetContextController = m_TargetController.GetRootNodeController(targetContext, 0) as VFXContextController;

                m_SourceControllersWithBlocks = m_SourceControllers.Concat(m_SourceBlockControllers);
                TransferEdges();
                UninitSmart();
            }
Ejemplo n.º 12
0
    public virtual SerializedProperty DoInspectorGUI()
    {
        var slotContainer = targets[0] as VFXModel;
        List <VFXSetting> settingFields = slotContainer.GetSettings(false, VFXSettingAttribute.VisibleFlags.InInspector).ToList();

        for (int i = 1; i < targets.Length; ++i)
        {
            IEnumerable <VFXSetting> otherSettingFields = (targets[i] as VFXModel).GetSettings(false, VFXSettingAttribute.VisibleFlags.InInspector).ToArray();

            var excluded = new HashSet <NameNType>(settingFields.Select(t => new NameNType()
            {
                name = t.name, type = t.field.FieldType
            }).Except(otherSettingFields.Select(t => new NameNType()
            {
                name = t.name, type = t.field.FieldType
            })));
            settingFields.RemoveAll(t => excluded.Any(u => u.name == t.name));
        }

        SerializedProperty modifiedSetting = null;

        foreach (var prop in settingFields.Select(t => new KeyValuePair <VFXSetting, SerializedProperty>(t, FindProperty(t))).Where(t => t.Value != null))
        {
            var fieldInfo = prop.Key.field;
            EditorGUI.BeginChangeCheck();
            var attrs = fieldInfo.GetCustomAttributes(typeof(StringProviderAttribute), true);
            if (attrs.Length > 0)
            {
                var strings = StringPropertyRM.FindStringProvider(attrs)();

                int selected = prop.Value.hasMultipleDifferentValues ? -1 : System.Array.IndexOf(strings, prop.Value.stringValue);
                int result   = EditorGUILayout.Popup(ObjectNames.NicifyVariableName(prop.Value.name), selected, strings);
                if (result != selected)
                {
                    prop.Value.stringValue = strings[result];
                }
            }
            else if (fieldInfo.FieldType.IsEnum && fieldInfo.FieldType.GetCustomAttributes(typeof(FlagsAttribute), false).Length == 0)
            {
                GUIContent[] enumNames  = null;
                int[]        enumValues = null;

                Array      enums  = Enum.GetValues(fieldInfo.FieldType);
                List <int> values = new List <int>(enums.Length);
                for (int i = 0; i < enums.Length; ++i)
                {
                    values.Add((int)enums.GetValue(i));
                }

                foreach (var target in targets)
                {
                    VFXModel targetIte = target as VFXModel;

                    var filteredValues = targetIte.GetFilteredOutEnumerators(fieldInfo.Name);
                    if (filteredValues != null)
                    {
                        foreach (int val in filteredValues)
                        {
                            values.Remove(val);
                        }
                    }
                }
                enumNames  = values.Select(t => new GUIContent(Enum.GetName(fieldInfo.FieldType, t))).ToArray();
                enumValues = values.ToArray();

                HeaderAttribute attr = fieldInfo.GetCustomAttributes <HeaderAttribute>().FirstOrDefault();

                if (attr != null)
                {
                    GUILayout.Label(attr.header, EditorStyles.boldLabel);
                }

                EditorGUILayout.IntPopup(prop.Value, enumNames, enumValues);
            }
            else
            {
                bool visibleChildren = EditorGUILayout.PropertyField(prop.Value);
                if (visibleChildren)
                {
                    SerializedProperty childProp = prop.Value.Copy();
                    while (childProp != null && childProp.NextVisible(visibleChildren) && childProp.propertyPath.StartsWith(prop.Value.propertyPath + "."))
                    {
                        visibleChildren = EditorGUILayout.PropertyField(childProp);
                    }
                }
            }
            if (EditorGUI.EndChangeCheck())
            {
                modifiedSetting = prop.Value;
            }
        }

        return(modifiedSetting);
    }
 public VFXVariableOperatorController(VFXModel model, VFXViewController viewController) : base(model, viewController)
 {
 }
 public VFXBranchOperatorController(VFXModel model, VFXViewController viewController) : base(model, viewController)
 {
 }
 public VFXNumericUniformOperatorController(VFXModel model, VFXViewController viewController) : base(model, viewController)
 {
 }
Ejemplo n.º 16
0
 protected override void OnInvalidate(VFXModel model, InvalidationCause cause)
 {
     s_logs.Add("OnInvalidate VFXModelB " + cause);
 }
 public void RemoveBlock(VFXBlock block)
 {
     model.RemoveChild(block);
     VFXModel.UnlinkModel(block);
 }
Ejemplo n.º 18
0
 private void OnModelInvalidated(VFXModel model, VFXModel.InvalidationCause cause)
 {
     s_logs.Add("OnInvalidateDelegate " + model + " " + cause);
 }
 public VFXUnifiedConstraintOperatorController(VFXModel model, VFXViewController viewController) : base(model, viewController)
 {
 }
Ejemplo n.º 20
0
        static void PasteNodes(VFXViewController viewController, Vector2 center, Data copyData, ScriptableObject[] allSerializedObjects, VFXView view, VFXGroupNodeController groupNode)
        {
            var     graph       = viewController.graph;
            Vector2 pasteOffset = (copyData.bounds.width > 0 && copyData.bounds.height > 0) ? center - copyData.bounds.center : Vector2.zero;

            // look if pasting there will result in the first element beeing exactly on top of other
            while (true)
            {
                bool foundSamePosition = false;
                if (copyData.contexts != null && copyData.contexts.Length > 0)
                {
                    VFXContext firstContext = copyData.contexts[0];

                    foreach (var existingContext in viewController.graph.children.OfType <VFXContext>())
                    {
                        if ((firstContext.position + pasteOffset - existingContext.position).sqrMagnitude < 1)
                        {
                            foundSamePosition = true;
                            break;
                        }
                    }
                }
                else if (copyData.slotContainers != null && copyData.slotContainers.Length > 0)
                {
                    VFXModel firstContainer = copyData.slotContainers[0];

                    foreach (var existingSlotContainer in viewController.graph.children.Where(t => t is IVFXSlotContainer))
                    {
                        if ((firstContainer.position + pasteOffset - existingSlotContainer.position).sqrMagnitude < 1)
                        {
                            foundSamePosition = true;
                            break;
                        }
                    }
                }
                else
                {
                    VFXUI ui = allSerializedObjects.OfType <VFXUI>().First();

                    if (ui != null)
                    {
                        if (ui.stickyNoteInfos != null && ui.stickyNoteInfos.Length > 0)
                        {
                            foreach (var stickyNote in viewController.stickyNotes)
                            {
                                if ((ui.stickyNoteInfos[0].position.position + pasteOffset - stickyNote.position.position).sqrMagnitude < 1)
                                {
                                    foundSamePosition = true;
                                    break;
                                }
                            }
                        }
                        else if (ui.groupInfos != null && ui.groupInfos.Length > 0)
                        {
                            foreach (var gn in viewController.groupNodes)
                            {
                                if ((ui.groupInfos[0].position.position + pasteOffset - gn.position.position).sqrMagnitude < 1)
                                {
                                    foundSamePosition = true;
                                    break;
                                }
                            }
                        }
                    }
                }

                if (foundSamePosition)
                {
                    pasteOffset += Vector2.one * 30;
                }
                else
                {
                    break;
                }
            }


            if (copyData.contexts != null)
            {
                foreach (var slotContainer in copyData.contexts)
                {
                    var newContext = slotContainer;
                    newContext.position += pasteOffset;
                    ClearLinks(newContext);
                }
            }

            if (copyData.slotContainers != null)
            {
                foreach (var slotContainer in copyData.slotContainers)
                {
                    var newSlotContainer = slotContainer;
                    newSlotContainer.position += pasteOffset;
                    ClearLinks(newSlotContainer as IVFXSlotContainer);
                }
            }


            for (int i = 0; i < allSerializedObjects.Length; ++i)
            {
                ScriptableObject obj = allSerializedObjects[i];

                if (obj is VFXContext || obj is VFXOperator)
                {
                    graph.AddChild(obj as VFXModel);
                }
                else if (obj is VFXParameter)
                {
                    int paramIndex = System.Array.FindIndex(copyData.parameters, t => t.index == i);

                    VFXParameter existingParameter = graph.children.OfType <VFXParameter>().FirstOrDefault(t => t.GetInstanceID() == copyData.parameters[paramIndex].originalInstanceID);
                    if (existingParameter != null)
                    {
                        // The original parameter is from the current graph, add the nodes to the original
                        copyData.parameters[paramIndex].parameter       = existingParameter;
                        copyData.parameters[paramIndex].copiedParameter = obj as VFXParameter;

                        copyData.parameters[paramIndex].infoIndexOffset = existingParameter.nodes.Count;

                        foreach (var info in copyData.parameters[paramIndex].infos)
                        {
                            info.position += pasteOffset;
                        }

                        var oldIDs = copyData.parameters[paramIndex].infos.ToDictionary(t => t, t => t.id);

                        existingParameter.AddNodeRange(copyData.parameters[paramIndex].infos);

                        //keep track of new ids for groupnodes
                        copyData.parameters[paramIndex].idMap = copyData.parameters[paramIndex].infos.ToDictionary(t => oldIDs[t], t => t.id);
                    }
                    else
                    {
                        // The original parameter is from another graph : create the parameter in the other graph, but replace the infos with only the ones copied.
                        copyData.parameters[paramIndex].parameter = obj as VFXParameter;
                        copyData.parameters[paramIndex].parameter.SetNodes(copyData.parameters[paramIndex].infos);

                        graph.AddChild(obj as VFXModel);
                    }
                }
            }


            VFXUI copiedUI              = allSerializedObjects.OfType <VFXUI>().FirstOrDefault();
            int   firstCopiedGroup      = -1;
            int   firstCopiedStickyNote = -1;

            if (copiedUI != null)
            {
                VFXUI ui = viewController.graph.UIInfos;
                firstCopiedStickyNote = ui.stickyNoteInfos != null ? ui.stickyNoteInfos.Length : 0;

                if (copiedUI.groupInfos != null && copiedUI.groupInfos.Length > 0)
                {
                    if (ui.groupInfos == null)
                    {
                        ui.groupInfos = new VFXUI.GroupInfo[0];
                    }
                    firstCopiedGroup = ui.groupInfos.Length;

                    foreach (var groupInfos in copiedUI.groupInfos)
                    {
                        for (int i = 0; i < groupInfos.contents.Length; ++i)
                        {
                            // if we link the parameter node to an existing parameter instead of the copied parameter we have to patch the groupnode content to point the that parameter with the correct id.
                            if (groupInfos.contents[i].model is VFXParameter)
                            {
                                VFXParameter parameter = groupInfos.contents[i].model as VFXParameter;
                                var          paramInfo = copyData.parameters.FirstOrDefault(t => t.copiedParameter == parameter);
                                if (paramInfo.parameter != null) // parameter will not be null unless the struct returned is the default.
                                {
                                    groupInfos.contents[i].model = paramInfo.parameter;
                                    groupInfos.contents[i].id    = paramInfo.idMap[groupInfos.contents[i].id];
                                }
                            }
                            else if (groupInfos.contents[i].isStickyNote)
                            {
                                groupInfos.contents[i].id += firstCopiedStickyNote;
                            }
                        }
                    }

                    ui.groupInfos = ui.groupInfos.Concat(copiedUI.groupInfos.Select(t => new VFXUI.GroupInfo(t)
                    {
                        position = new Rect(t.position.position + pasteOffset, t.position.size)
                    })).ToArray();
                }
                if (copiedUI.stickyNoteInfos != null && copiedUI.stickyNoteInfos.Length > 0)
                {
                    if (ui.stickyNoteInfos == null)
                    {
                        ui.stickyNoteInfos = new VFXUI.StickyNoteInfo[0];
                    }
                    ui.stickyNoteInfos = ui.stickyNoteInfos.Concat(copiedUI.stickyNoteInfos.Select(t => new VFXUI.StickyNoteInfo(t)
                    {
                        position = new Rect(t.position.position + pasteOffset, t.position.size)
                    })).ToArray();
                }
            }

            CopyDataEdges(copyData, allSerializedObjects);


            if (copyData.flowEdges != null)
            {
                foreach (var flowEdge in copyData.flowEdges)
                {
                    VFXContext inputContext  = allSerializedObjects[flowEdge.input.contextIndex] as VFXContext;
                    VFXContext outputContext = allSerializedObjects[flowEdge.output.contextIndex] as VFXContext;

                    inputContext.LinkFrom(outputContext, flowEdge.input.flowIndex, flowEdge.output.flowIndex);
                }
            }

            foreach (var dataAndContexts in copyData.dataAndContexts)
            {
                VFXData data = allSerializedObjects[dataAndContexts.dataIndex] as VFXData;

                foreach (var contextIndex in dataAndContexts.contextsIndexes)
                {
                    VFXContext context = allSerializedObjects[contextIndex] as VFXContext;
                    data.CopySettings(context.GetData());
                }
            }

            // Create all ui based on model
            viewController.LightApplyChanges();

            if (view != null)
            {
                view.ClearSelection();

                var elements = view.graphElements.ToList();


                List <VFXNodeUI>    newSlotContainerUIs = new List <VFXNodeUI>();
                List <VFXContextUI> newContextUIs       = new List <VFXContextUI>();

                foreach (var slotContainer in allSerializedObjects.OfType <VFXContext>())
                {
                    VFXContextUI contextUI = elements.OfType <VFXContextUI>().FirstOrDefault(t => t.controller.model == slotContainer);
                    if (contextUI != null)
                    {
                        newSlotContainerUIs.Add(contextUI);
                        newSlotContainerUIs.AddRange(contextUI.GetAllBlocks().Cast <VFXNodeUI>());
                        newContextUIs.Add(contextUI);
                        view.AddToSelection(contextUI);
                    }
                }
                foreach (var slotContainer in allSerializedObjects.OfType <VFXOperator>())
                {
                    VFXOperatorUI slotContainerUI = elements.OfType <VFXOperatorUI>().FirstOrDefault(t => t.controller.model == slotContainer);
                    if (slotContainerUI != null)
                    {
                        newSlotContainerUIs.Add(slotContainerUI);
                        view.AddToSelection(slotContainerUI);
                    }
                }

                foreach (var param in copyData.parameters)
                {
                    foreach (var parameterUI in elements.OfType <VFXParameterUI>().Where(t => t.controller.model == param.parameter && param.parameter.nodes.IndexOf(t.controller.infos) >= param.infoIndexOffset))
                    {
                        newSlotContainerUIs.Add(parameterUI);
                        view.AddToSelection(parameterUI);
                    }
                }

                // Simply selected all data edge with the context or slot container, they can be no other than the copied ones
                foreach (var dataEdge in elements.OfType <VFXDataEdge>())
                {
                    if (newSlotContainerUIs.Contains(dataEdge.input.GetFirstAncestorOfType <VFXNodeUI>()))
                    {
                        view.AddToSelection(dataEdge);
                    }
                }
                // Simply selected all data edge with the context or slot container, they can be no other than the copied ones
                foreach (var flowEdge in elements.OfType <VFXFlowEdge>())
                {
                    if (newContextUIs.Contains(flowEdge.input.GetFirstAncestorOfType <VFXContextUI>()))
                    {
                        view.AddToSelection(flowEdge);
                    }
                }

                if (groupNode != null)
                {
                    foreach (var newSlotContainerUI in newSlotContainerUIs)
                    {
                        groupNode.AddNode(newSlotContainerUI.controller);
                    }
                }

                //Select all groups that are new
                if (firstCopiedGroup >= 0)
                {
                    foreach (var gn in elements.OfType <VFXGroupNode>())
                    {
                        if (gn.controller.index >= firstCopiedGroup)
                        {
                            view.AddToSelection(gn);
                        }
                    }
                }

                //Select all groups that are new
                if (firstCopiedStickyNote >= 0)
                {
                    foreach (var gn in elements.OfType <VFXStickyNote>())
                    {
                        if (gn.controller.index >= firstCopiedStickyNote)
                        {
                            view.AddToSelection(gn);
                        }
                    }
                }
            }
        }
 public VFXCascadedOperatorController(VFXModel model, VFXViewController viewController) : base(model, viewController)
 {
 }