예제 #1
0
		protected virtual bool StartEditMode(Camera camera)
		{
			if (editMode == EditMode.EditShape ||
				editMode == EditMode.ExtrudeShape)
			{
				return false;
			}

			Undo.RecordObject(this, "Created shape");
			if (GUIUtility.hotControl == shapeId)
			{
				GUIUtility.hotControl = 0;
				GUIUtility.keyboardControl = 0;
				EditorGUIUtility.SetWantsMouseJumping(0);
				EditorGUIUtility.editingTextField = false;
			}
			
			CalculateWorldSpaceTangents(camera);
			brushPosition = buildPlane.Project(ShapeSettings.GetCenter(buildPlane));
			editMode = EditMode.EditShape;

			CSGPlane newPlane = buildPlane;
			ShapeSettings.CalculatePlane(ref newPlane);
			if (newPlane.normal.sqrMagnitude != 0)
				buildPlane = newPlane;

            if (ModelTraits.IsModelEditable(geometryModel))
                SelectionUtility.LastUsedModel = geometryModel;

			UpdateBaseShape();

			//StartExtrudeMode();
			//GrabHeightHandle(ignoreFirstMouseUp: true);
			return true;
		}
예제 #2
0
        protected bool GenerateBrushObjects(int brushObjectCount, bool inGridSpace = true)
        {
            Undo.IncrementCurrentGroup();
            undoGroupIndex = Undo.GetCurrentGroup();

            var lastUsedModel = SelectionUtility.LastUsedModel;

            if (!ModelTraits.IsModelEditable(lastUsedModel))
            {
                lastUsedModel = null;
            }
            var lastUsedModelTransform = !lastUsedModel ? null : lastUsedModel.transform;

            if (!lastUsedModelTransform ||
                !lastUsedModel.isActiveAndEnabled)
            {
                if (prevSelection != null && prevSelection.Length > 0)
                {
                    for (int i = 0; i < prevSelection.Length; i++)
                    {
                        UnityEngine.Object obj   = prevSelection[i];
                        CSGBrush           brush = obj as CSGBrush;
                        MonoBehaviour      mono  = obj as MonoBehaviour;
                        GameObject         go    = obj as GameObject;
                        if (!brush)
                        {
                            if (mono)
                            {
                                brush = mono.GetComponentInChildren <CSGBrush>();
                            }
                            if (go)
                            {
                                brush = go.GetComponentInChildren <CSGBrush>();
                            }
                        }

                        if (!brush)
                        {
                            continue;
                        }

                        if ((brush.gameObject.hideFlags & (HideFlags.HideInHierarchy | HideFlags.NotEditable | HideFlags.DontSaveInBuild)) != 0)
                        {
                            continue;
                        }

                        if (brush.ChildData == null ||
                            brush.ChildData.ModelTransform == null)
                        {
                            continue;
                        }

                        var model = brush.ChildData.Model;
                        if (!model ||
                            !model.isActiveAndEnabled)
                        {
                            continue;
                        }

                        lastUsedModelTransform = brush.ChildData.ModelTransform;
                        break;
                    }
                }
            }

            if (generatedBrushes != null && generatedBrushes.Length > 0)
            {
                for (int i = generatedBrushes.Length - 1; i >= 0; i--)
                {
                    if (generatedBrushes[i])
                    {
                        continue;
                    }
                    ArrayUtility.RemoveAt(ref generatedBrushes, i);
                }
                for (int i = generatedGameObjects.Length - 1; i >= 0; i--)
                {
                    if (generatedGameObjects[i])
                    {
                        var brush = generatedGameObjects[i].GetComponentInChildren <CSGBrush>();
                        if (brush && ArrayUtility.Contains(generatedBrushes, brush))
                        {
                            continue;
                        }
                    }
                    ArrayUtility.RemoveAt(ref generatedGameObjects, i);
                }
            }

            if (generatedGameObjects == null ||
                generatedGameObjects.Length != brushObjectCount)
            {
                if (generatedBrushes != null && generatedBrushes.Length > 0)
                {
                    for (int i = 0; i < generatedBrushes.Length; i++)
                    {
                        InternalCSGModelManager.OnDestroyed(generatedBrushes[i]);
                        GameObject.DestroyImmediate(generatedBrushes[i]);
                    }
                }
                if (generatedGameObjects != null && generatedGameObjects.Length > 0)
                {
                    for (int i = 0; i < generatedGameObjects.Length; i++)
                    {
                        GameObject.DestroyImmediate(generatedGameObjects[i]);
                    }
                }

                if (parentGameObject != null)
                {
                    GameObject.DestroyImmediate(parentGameObject);
                }

                //DebugEditorWindow.PrintDebugInfo();

                if (lastUsedModelTransform == null)
                {
                    parentGameObject = OperationsUtility.CreateGameObject(lastUsedModelTransform, "Model", true);
                    InternalCSGModelManager.CreateCSGModel(parentGameObject);
                    parentModel = parentGameObject.GetComponent <CSGModel>();
                    Undo.RegisterCreatedObjectUndo(parentGameObject, "Created model");

                    if (brushObjectCount > 1)
                    {
                        operationGameObject = OperationsUtility.CreateGameObject(parentGameObject.transform, "Operation", true);
                        var transform = operationGameObject.transform;
                        SetBrushTransformation(transform);

                        var operation = operationGameObject.AddComponent <CSGOperation>();
                        if (CurrentCSGOperationType != invalidCSGOperationType)
                        {
                            operation.OperationType = CurrentCSGOperationType;
                        }
                        operation.HandleAsOne = true;
                        Undo.RegisterCreatedObjectUndo(operationGameObject, "Created operation");
                        parentTransform = operationGameObject.transform;
                    }
                    else
                    {
                        parentTransform = parentGameObject.transform;
                    }
                }
                else
                if (brushObjectCount > 1)
                {
                    parentModel      = lastUsedModelTransform.GetComponent <CSGModel>();
                    parentGameObject = OperationsUtility.CreateGameObject(lastUsedModelTransform, "Brushes", true);
                    var transform = parentGameObject.transform;
                    SetBrushTransformation(transform);

                    operationGameObject = parentGameObject;
                    var operation = operationGameObject.AddComponent <CSGOperation>();
                    if (CurrentCSGOperationType != invalidCSGOperationType)
                    {
                        operation.OperationType = CurrentCSGOperationType;
                    }
                    operation.HandleAsOne = true;
                    parentTransform       = operationGameObject.transform;
                    Undo.RegisterCreatedObjectUndo(parentGameObject, "Created brush");
                }
                else
                {
                    parentGameObject    = null;
                    operationGameObject = null;
                    parentTransform     = lastUsedModelTransform;
                    parentModel         = lastUsedModelTransform.GetComponent <CSGModel>();
                }


                generatedGameObjects = new GameObject[brushObjectCount];
                generatedBrushes     = new CSGBrush[brushObjectCount];
                for (int p = 0; p < brushObjectCount; p++)
                {
                    string name;
                    if (brushObjectCount == 1)
                    {
                        name = "Brush";
                    }
                    else
                    {
                        name = "Brush (" + p + ")";
                    }
                    var gameObject = OperationsUtility.CreateGameObject(parentTransform, name, false);
                    gameObject.SetActive(false);

                    var brushComponent = gameObject.AddComponent <CSGBrush>();

                    if (operationGameObject == null)
                    {
                        if (CurrentCSGOperationType != invalidCSGOperationType)
                        {
                            brushComponent.OperationType = CurrentCSGOperationType;
                        }
                        operationGameObject = gameObject;
                        var transform = gameObject.transform;
                        SetBrushTransformation(transform);
                    }

                    generatedBrushes[p]             = brushComponent;
                    generatedBrushes[p].ControlMesh = new ControlMesh();
                    generatedBrushes[p].Shape       = new Shape();
                    Undo.RegisterCreatedObjectUndo(gameObject, "Created brush");
                    generatedGameObjects[p] = gameObject;
                }
                //InternalCSGModelManager.Refresh(forceHierarchyUpdate: true);
                // brushes not registered at this point!??


                //DebugEditorWindow.PrintDebugInfo();
                //Selection.objects = generatedGameObjects;
            }
            else
            {
                UpdateBrushPosition();
            }

            return(generatedBrushes != null && generatedBrushes.Length > 0 && generatedBrushes.Length == brushObjectCount);
        }
        public static bool UpdateMeshes(System.Text.StringBuilder text = null, bool forceUpdate = false)
        {
            if (EditorApplication.isPlaying ||
                EditorApplication.isPlayingOrWillChangePlaymode)
            {
                return(false);
            }

            if (inUpdateMeshes)
            {
                return(false);
            }

            MeshInstanceManager.Update();

            var unityMeshUpdates       = 0.0;
            var getMeshDescriptionTime = 0.0;

            getMeshInstanceTime = 0.0;
            getModelMeshesTime  = 0.0;
            updateMeshTime      = 0.0;

            inUpdateMeshes = true;
            try
            {
                if (External == null)
                {
                    return(false);
                }

                if (forcedUpdateRequired)
                {
                    forceUpdate          = true;
                    forcedUpdateRequired = false;
                }

                var modelCount = Models.Length;
                if (modelCount == 0)
                {
                    return(false);
                }

                for (var i = 0; i < modelCount; i++)
                {
                    var model = Models[i];

                    if (!forceUpdate &&
                        !model.forceUpdate)
                    {
                        continue;
                    }

                    if (!ModelTraits.IsModelEditable(model))
                    {
                        continue;
                    }

                    External.SetDirty(model.modelNodeID);
                    model.forceUpdate = false;
                }

                // update the model meshes
                if (!External.UpdateAllModelMeshes())
                {
                    return(false);                    // nothing to do
                }
                MeshGeneration++;
                bool haveUpdates = forceUpdate;
                for (var i = 0; i < modelCount; i++)
                {
                    var model = Models[i];

                    if (!(new CSGTreeNode {
                        nodeID = model.modelNodeID
                    }.Dirty))
                    {
                        continue;
                    }

                    var meshContainer = model.generatedMeshes;
                    if (!meshContainer)
                    {
                        continue;
                    }

                    EnsureInitialized(model);

                    bool needToUpdateMeshes;
                    var  startGetMeshDescriptionTime = EditorApplication.timeSinceStartup;
                    {
                        needToUpdateMeshes = External.GetMeshDescriptions(model, ref __meshDescriptions);
                    }
                    getMeshDescriptionTime += EditorApplication.timeSinceStartup - startGetMeshDescriptionTime;


                    if (!ModelTraits.IsModelEditable(model))
                    {
                        continue;
                    }

                    if (!needToUpdateMeshes)
                    {
                        continue;
                    }

                    __foundHelperSurfaces.Clear();
                    __foundGeneratedMeshInstance.Clear();
                    __unfoundMeshInstances.Clear();
                    {
                        var startUnityMeshUpdates = EditorApplication.timeSinceStartup;
                        for (int meshIndex = 0; meshIndex < __meshDescriptions.Length; meshIndex++)
                        {
                            if (!ValidateMesh(__meshDescriptions[meshIndex]))
                            {
                                continue;
                            }

                            haveUpdates = true;
                            var renderSurfaceType = MeshInstanceManager.GetSurfaceType(__meshDescriptions[meshIndex], model.Settings);
                            if (renderSurfaceType == RenderSurfaceType.Normal ||
                                renderSurfaceType == RenderSurfaceType.ShadowOnly ||
                                renderSurfaceType == RenderSurfaceType.Collider ||
                                renderSurfaceType == RenderSurfaceType.Trigger)
                            {
                                GeneratedMeshInstance meshInstance;
                                if (TryGetMeshInstance(meshContainer, model, model.Settings, __meshDescriptions[meshIndex], renderSurfaceType, out meshInstance))
                                {
                                    if (meshInstance != null)
                                    {
                                        __foundGeneratedMeshInstance.Add(meshInstance);
                                    }
                                    else
                                    {
                                        __unfoundMeshInstances.Add(meshIndex);
                                    }
                                }
                            }
                            if (renderSurfaceType != RenderSurfaceType.Normal)
                            {
                                HelperSurfaceDescription helperSurface;
                                if (TryGetHelperSurfaceDescription(meshContainer, model, model.Settings, __meshDescriptions[meshIndex], renderSurfaceType, out helperSurface))
                                {
                                    if (helperSurface != null)
                                    {
                                        __foundHelperSurfaces.Add(helperSurface);
                                    }
                                    else
                                    {
                                        __unfoundMeshInstances.Add(meshIndex);
                                    }
                                }
                            }
                        }

                        var unusedInstances = MeshInstanceManager.FindUnusedMeshInstances(meshContainer, __foundGeneratedMeshInstance, __foundHelperSurfaces);

                        foreach (int meshIndex in __unfoundMeshInstances)
                        {
                            haveUpdates = true;
                            var renderSurfaceType = MeshInstanceManager.GetSurfaceType(__meshDescriptions[meshIndex], model.Settings);
                            if (renderSurfaceType == RenderSurfaceType.Normal ||
                                renderSurfaceType == RenderSurfaceType.ShadowOnly ||
                                renderSurfaceType == RenderSurfaceType.Collider ||
                                renderSurfaceType == RenderSurfaceType.Trigger)
                            {
                                var meshInstance = GenerateMeshInstance(meshContainer, model, model.Settings, __meshDescriptions[meshIndex], renderSurfaceType, unusedInstances);
                                if (meshInstance != null)
                                {
                                    __foundGeneratedMeshInstance.Add(meshInstance);
                                }
                            }
                            if (renderSurfaceType != RenderSurfaceType.Normal)
                            {
                                var helperSurface = GenerateHelperSurfaceDescription(meshContainer, model, model.Settings, __meshDescriptions[meshIndex], renderSurfaceType);
                                __foundHelperSurfaces.Add(helperSurface);
                            }
                        }

                        MeshInstanceManager.UpdateContainerComponents(meshContainer, __foundGeneratedMeshInstance, __foundHelperSurfaces);
                        unityMeshUpdates += (EditorApplication.timeSinceStartup - startUnityMeshUpdates);
                    }
                }

                if (haveUpdates)
                {
                    MeshInstanceManager.UpdateHelperSurfaceVisibility(force: true);
                }


                if (text != null)
                {
                    text.AppendFormat(System.Globalization.CultureInfo.InvariantCulture,
                                      "All mesh generation {0:F} ms " +
                                      "+ retrieving {1:F} ms " +
                                      "+ Unity mesh updates {2:F} ms " +
                                      "+ overhead {3:F} ms. ",
                                      getMeshDescriptionTime * 1000,
                                      getModelMeshesTime * 1000,
                                      updateMeshTime * 1000,
                                      (unityMeshUpdates - (getModelMeshesTime + updateMeshTime)) * 1000);
                }

                return(true);
            }
            finally
            {
                inUpdateMeshes = false;
            }
        }
        public static bool UpdateModelSettings()
        {
            var forceHierarchyUpdate = false;

            for (var i = 0; i < Models.Length; i++)
            {
                var model = Models[i];
                if (!ModelTraits.IsModelEditable(model))
                {
                    continue;
                }
                var modelModified = false;
                var invertedWorld = model.InvertedWorld;
                if (invertedWorld)
                {
                    if (model.infiniteBrush == null)
                    {
                        CSGBrush infiniteBrush = null;
                        var      childNodes    = model.GetComponentsInChildren <CSGBrush>();
                        for (int c = 0; c < childNodes.Length; c++)
                        {
                            if (childNodes[c].Flags == BrushFlags.InfiniteBrush)
                            {
                                if (infiniteBrush != null)
                                {
                                    UnityEngine.Object.DestroyImmediate(childNodes[c]);
                                }
                                else
                                {
                                    infiniteBrush = childNodes[c];
                                }
                            }
                        }

                        if (infiniteBrush == null)
                        {
                            var gameObject = new GameObject("*hidden infinite brush*");
                            gameObject.hideFlags = MeshInstanceManager.ComponentHideFlags;
                            gameObject.transform.SetParent(model.transform, false);
                            infiniteBrush = gameObject.AddComponent <CSGBrush>();
                        }

                        model.infiniteBrush       = infiniteBrush;
                        model.infiniteBrush.Flags = BrushFlags.InfiniteBrush;

                        modelModified = true;
                    }
                    if (model.infiniteBrush.transform.GetSiblingIndex() != 0)
                    {
                        model.infiniteBrush.transform.SetSiblingIndex(0);
                        modelModified = true;
                    }
                }
                else
                {
                    if (model.infiniteBrush)
                    {
                        if (model.infiniteBrush.gameObject)
                        {
                            UnityEngine.Object.DestroyImmediate(model.infiniteBrush.gameObject);
                        }
                        model.infiniteBrush = null;
                        modelModified       = true;
                    }
                }
                if (modelModified)
                {
                    var childBrushes = model.GetComponentsInChildren <CSGBrush>();
                    for (int j = 0; j < childBrushes.Length; j++)
                    {
                        if (!childBrushes[j] ||
                            childBrushes[j].ControlMesh == null)
                        {
                            continue;
                        }
                        childBrushes[j].ControlMesh.Generation++;
                    }
                    forceHierarchyUpdate = true;
                }
            }
            return(forceHierarchyUpdate);
        }
        public static void DoSelectionClick(SceneView sceneView, bool ignoreInvisibleSurfaces = true)
        {
            var        camera = sceneView.camera;
            GameObject gameobject;

            SceneQueryUtility.FindClickWorldIntersection(camera, Event.current.mousePosition, out gameobject, ignoreInvisibleSurfaces);

            gameobject = SceneQueryUtility.FindSelectionBase(gameobject);

            var  selectedObjectsOnClick = new List <int>(Selection.instanceIDs);
            bool addedSelection         = false;

            if (EditorGUI.actionKey)
            {
                if (gameobject != null)
                {
                    var instanceID = gameobject.GetInstanceID();
                    if (selectedObjectsOnClick.Contains(instanceID))
                    {
                        selectedObjectsOnClick.Remove(instanceID);
                    }
                    else
                    {
                        selectedObjectsOnClick.Add(instanceID);
                        addedSelection = true;
                    }

                    if (selectedObjectsOnClick.Count == 0)
                    {
                        Selection.activeTransform = null;
                    }
                    else
                    {
                        Selection.instanceIDs = selectedObjectsOnClick.ToArray();
                    }
                }
            }
            else
            if (Event.current.shift)
            {
                if (gameobject != null)
                {
                    var instanceID = gameobject.GetInstanceID();
                    selectedObjectsOnClick.Add(instanceID);
                    Selection.instanceIDs = selectedObjectsOnClick.ToArray();
                    addedSelection        = true;
                }
            }
            else
            if (Event.current.alt)
            {
                if (gameobject != null)
                {
                    var instanceID = gameobject.GetInstanceID();
                    selectedObjectsOnClick.Remove(instanceID);
                    Selection.instanceIDs = selectedObjectsOnClick.ToArray();
                    return;
                }
            }
            else
            {
                Selection.activeGameObject = gameobject;
                addedSelection             = true;
            }

            if (!addedSelection)
            {
                foreach (var item in Selection.GetFiltered(typeof(CSGBrush), SelectionMode.Deep))
                {
                    var brush = item as CSGBrush;
                    if (brush.ChildData == null ||
                        !ModelTraits.IsModelEditable(brush.ChildData.Model))
                    {
                        continue;
                    }
                    SelectionUtility.LastUsedModel = brush.ChildData.Model;
                    break;
                }
            }
            else
            if (gameobject != null)
            {
                var brush = gameobject.GetComponent <CSGBrush>();
                if (brush != null)
                {
                    if (brush.ChildData == null ||
                        !ModelTraits.IsModelEditable(brush.ChildData.Model))
                    {
                        return;
                    }
                    SelectionUtility.LastUsedModel = brush.ChildData.Model;
                }
            }
        }
예제 #6
0
        public bool UpdateSelection(HashSet <CSGNode> newTargetNodes, HashSet <Transform> newTargetOthers)
        {
            if (newTargetNodes == null)
            {
                newTargetNodes = new HashSet <CSGNode>();
            }
            if (newTargetOthers == null)
            {
                newTargetOthers = new HashSet <Transform>();
            }

            this.RemovedNodes  = null;
            this.RemovedOthers = null;

            this.AddedNodes  = null;
            this.AddedOthers = null;

            var foundRemovedNodes = new List <CSGNode>();

            if (this.NodeTargets != null &&
                this.NodeTargets.Length > 0)
            {
                if (newTargetNodes.Count == 0)
                {
                    foundRemovedNodes.AddRange(this.NodeTargets);
                }
                else
                {
                    for (int i = 0; i < this.NodeTargets.Length; i++)
                    {
                        if (!this.NodeTargets[i] ||
                            !newTargetNodes.Contains(this.NodeTargets[i]))
                        {
                            foundRemovedNodes.Add(this.NodeTargets[i]);
                        }
                    }
                }
            }

            var foundRemovedOthers = new List <Transform>();

            if (this.OtherTargets != null &&
                this.OtherTargets.Length > 0)
            {
                if (newTargetOthers.Count == 0)
                {
                    foundRemovedOthers.AddRange(this.OtherTargets);
                }
                else
                {
                    for (int i = 0; i < this.OtherTargets.Length; i++)
                    {
                        if (!this.OtherTargets[i] ||
                            !newTargetOthers.Contains(this.OtherTargets[i]))
                        {
                            foundRemovedOthers.Add(this.OtherTargets[i]);
                        }
                    }
                }
            }

            var originalTargetNodeCount  = (this.NodeTargets == null) ? 0 : this.NodeTargets.Length;
            var originalTargetOtherCount = (this.OtherTargets == null) ? 0 : this.OtherTargets.Length;

            // If our counts are the same and nothing is removed (and nothing could've been added), nothing has changed.
            if (newTargetNodes.Count == originalTargetNodeCount &&
                newTargetOthers.Count == originalTargetOtherCount &&
                foundRemovedNodes.Count == 0 &&
                foundRemovedOthers.Count == 0)
            {
                return(false);
            }

            Validate();

            foreach (var node in foundRemovedNodes)
            {
                ArrayUtility.Remove(ref this.NodeTargets, node);

                var brush = node as CSGBrush;
                if (brush != null)
                {
                    ArrayUtility.Remove(ref this.BrushTargets, brush);
                    continue;
                }
                var operation = node as CSGOperation;
                if (node is CSGOperation)
                {
                    ArrayUtility.Remove(ref this.OperationTargets, operation);
                    continue;
                }
                var model = node as CSGModel;
                if (node is CSGModel)
                {
                    ArrayUtility.Remove(ref this.ModelTargets, model);
                    continue;
                }
            }

            foreach (var other in foundRemovedOthers)
            {
                ArrayUtility.Remove(ref this.OtherTargets, other);
            }

            var foundAddedNodes = new List <CSGNode>();

            foreach (var node in newTargetNodes)
            {
                if (this.NodeTargets != null &&
                    ArrayUtility.Contains(this.NodeTargets, node))
                {
                    continue;
                }

                if (this.NodeTargets == null)
                {
                    this.NodeTargets = new CSGNode[] { node };
                }
                else
                {
                    ArrayUtility.Add(ref this.NodeTargets, node);
                }

                foundAddedNodes.Add(node);

                if (CSGPrefabUtility.IsPrefabAsset(node.gameObject))
                {
                    continue;
                }

                var brush = node as CSGBrush;
                if (brush != null)
                {
                    if (this.BrushTargets == null)
                    {
                        this.BrushTargets = new CSGBrush[] { brush }
                    }
                    ;
                    else
                    {
                        ArrayUtility.Add(ref this.BrushTargets, brush);
                    }
                    continue;
                }
                var operation = node as CSGOperation;
                if (node is CSGOperation)
                {
                    if (this.OperationTargets == null)
                    {
                        this.OperationTargets = new CSGOperation[] { operation }
                    }
                    ;
                    else
                    {
                        ArrayUtility.Add(ref this.OperationTargets, operation);
                    }
                    continue;
                }
                var model = node as CSGModel;
                if (node is CSGModel)
                {
                    if (this.ModelTargets == null)
                    {
                        this.ModelTargets = new CSGModel[] { model }
                    }
                    ;
                    else
                    {
                        ArrayUtility.Add(ref this.ModelTargets, model);
                    }
                    continue;
                }
            }

            var foundAddedOthers = new List <Transform>();

            foreach (var other in newTargetOthers)
            {
                if (this.OtherTargets != null &&
                    ArrayUtility.Contains(this.OtherTargets, other))
                {
                    continue;
                }

                if (this.OtherTargets == null)
                {
                    this.OtherTargets = new Transform[] { other }
                }
                ;
                else
                {
                    ArrayUtility.Add(ref this.OtherTargets, other);
                }
                foundAddedOthers.Add(other);
            }

            for (int i = foundAddedNodes.Count - 1; i >= 0; i--)
            {
                var node  = foundAddedNodes[i];
                var brush = node as CSGBrush;
                if (brush != null)
                {
                    if (brush.ChildData == null ||
                        brush.ChildData.Model == null)
                    {
                        continue;
                    }

                    var childModel = brush.ChildData.Model;
                    if (ModelTraits.IsModelEditable(childModel))
                    {
                        SelectionUtility.LastUsedModel = childModel;
                    }
                    break;
                }
                var operation = node as CSGOperation;
                if (operation != null)
                {
                    if (operation.ChildData == null ||
                        operation.ChildData.Model == null)
                    {
                        continue;
                    }

                    SelectionUtility.LastUsedModel = operation.ChildData.Model;
                    break;
                }
                var model = node as CSGModel;
                if (ModelTraits.IsModelEditable(model))
                {
                    SelectionUtility.LastUsedModel = model;
                    break;
                }
            }

            this.RemovedNodes  = foundRemovedNodes.ToArray();
            this.RemovedOthers = foundRemovedOthers.ToArray();

            this.AddedNodes  = foundAddedNodes.ToArray();
            this.AddedOthers = foundAddedOthers.ToArray();

            return(foundAddedNodes.Count > 0 || foundRemovedNodes.Count > 0 || foundAddedOthers.Count > 0 || foundRemovedOthers.Count > 0);
        }